見出し画像

自動保存の致命的なバグを修正しました | ハックフォープレイ

サムネイルは RxJS の debounceTime より拝借しました

ハックフォープレイのステージはログインしていれば自動保存されますが、それが上手く動かず、せっかく作ったステージが保存されていなかった、という話をしばしば耳にします。改めてコードを読んでみると、良くない実装になっていたことが分かったので、この問題を修正しました。

1.アップロード処理が同時に走っていた

前回の自動保存が終わらないうちに次の自動保存を開始してしまうと、複数のアップロード処理が同時に走ることになります。これだけなら問題ないのですが、ある処理の終了イベントを受け取って「保存されました」と表示をするよう実装していたため、まだ他の処理が終わっていないのに「保存されました」と表示されてしまうバグがありました。

この問題は、複数のアップロード処理が同時に走らないようにすることで、解決しました。しかし、今度は別の問題が出てしまいました。


2.変更を debounce してアップロードを開始すると失敗時に自動でリトライしてくれない

debounce とは、不定期に発生するイベントを一定時間毎にまとめることで処理を効率化するテクニックです。非同期処理の実装ではよく使われます。

画像1

RxJS の debounceTime より拝借

ハックフォープレイでは、コードを書き換えて「プレイ」すると、図でいう上の線に新たな玉が送られ、それから1秒間新たな玉がやってこなければ、下の線に玉が送られ、アップロードを開始する実装になっていました。

この実装の問題点は失敗時のリトライを手動で行う必要があるということです。具体的には「わざと意味のない文字を書いてプレイボタンを押す」という行動が必要でした。

修正後(現在)は、 interval と filter を使って自動リトライを行います。

画像2

interval はユーザーの行動によらず、必ず一定時間おきに処理を行います。

画像3

filter は、条件に一致した場合のみ処理を行います。今回の場合、変更があった場合のみアップロードするという具合です。

この修正により自動保存のバグはおおむね解消されましたが、アップロード処理に時間を要する場合、挙動が不安定になる可能性がありました。


3.自動セーブが出来ているかどうかをフラグで管理していると、アップロード中に発生した変更を取りこぼす

ここでフラグとは true/false の値を取れる真偽値のことをいいます。今までの実装ではファイルに変更があったかどうかをフラグで管理していました。そのため、アップロードの最中にファイルを変更した場合、アップロード後にフラグを false に戻してしまうため、変更がなかったことになっていたのです。これが上手く保存できなかった原因だったと考えられます。

この問題は、フラグではなくカウンタ(数値)を用いて、ファイルが変更された回数を 1, 2, 3... と管理していくことで解決できました。最後にアップロードされたのが何回目のときだったかを記録しておき、今の変更回数と比較すれば、最新のファイルがアップロードされたかどうかが分かる訳です。


最後に

ハックフォープレイでは、ユーザーの皆さんから寄せられたご意見や不具合などに積極的に対応しています。もし不具合かな?と思ったら、「いつ」「誰が」「何をしたときに」「どんな」ことが起こったのか右下のチャットにご報告いただけると助かります。

この記事が気に入ったらサポートをしてみませんか?