概要: WebページとWebワーカーの両方からIndexedDBにアクセスすることで、競合状態を回避しようとしています。
セットアップ: ユーザーがサイトで作業しているときにローカルのIndexedDBにアイテムを保存しているWebページ。ユーザーがローカルDBにデータを保存するたびに、レコードは「未送信」としてマークされます。
IndexedDBからデータをプルしてサーバーに送信し、サーバーがデータを受信すると、IndexedDB内のデータを「送信済み」としてマークするWebワーカーのバックグラウンドスレッド。
問題: IndexedDBへのアクセスは非同期であるため、Webワーカーがレコードをサーバーに送信すると同時にユーザーがレコードを更新しないことを保証できません。タイムラインを以下に示します。
- Web-workerはDBからデータを取得し、それをサーバーに送信します
- 転送が行われている間、ユーザーはデータを更新してDBに保存します。
- Webワーカーはサーバーから応答を取得し、DBを「送信済み」に更新します
- サーバーに送信されていないが「送信済み」とマークされたデータがDBにあります
失敗した解決策: サーバーから応答を受け取った後、行を再確認して、何かが変更されているかどうかを確認できます。ただし、データをDBに書き込むことができる小さなウィンドウがまだ残っており、サーバーにデータが送信されることはありません。
例:サーバーがデータが保存されたと言った後、次のようにします。
IndexedDB.HasDataChanged(
function(changed) {
// Since this is async, this changed boolean could be lying.
// The data might have been updated after I checked and before I was called.
if (!changed){
IndexedDB.UpdateToSent() }
});
その他の注意事項: W3仕様に準拠した同期APIがありますが、まだ誰も実装していないため、使用できません(http://www.w3.org/TR/IndexedDB/#sync-database)。同期APIは、私が想定するこの正確な状況を回避するために、Webワーカーが使用するように設計されています。
これについての考えは大歓迎です。約1週間取り組んできましたが、うまくいくものを思い付くことができませんでした。