8
  1. 何かがタスクを要求します
  2. 他の人がタスクリストをストレージから取り出してそこにタスクがあるかどうかを確認します。
  3. タスクがある場合、タスクが削除され、小さい「タスクリスト」がストレージに戻されます。複数の要求が発生した場合、ステップ2と3の間

競合状態が発生する可能性がありますし、同じタスクが二回提供されます。複数のchrome.storage APIコールの競合状態を防ぐ最も良い方法は?

他の要求を防ぐために、1つのタスクが「チェックアウト」されているときに「タスクテーブル」を「ロック」する正しい解決法はありますか?

実行の遅延などのパフォーマンスの影響が最も少ないソリューションと、chrome.storage APIを使用したjavascriptでの実装方法を教えてください。例えば

いくつかのコード:

function decide_response () { 
    if(script.replay_type == "reissue") { 
      function next_task(tasks) { 
       var no_tasks = (tasks.length == 0); 
       if(no_tasks) { 
        target_complete_responses.close_requester(); 
       } 
       else { 
        var next_task = tasks.pop(); 
        function notify_execute() { 
         target_complete_responses.notify_requester_execute(next_task); 
        } 
        setTable("tasks", tasks, notify_execute); 
       } 
      } 
      getTable("tasks", next_tasks); 
    ... 
    } 
... 
} 
+0

Nice edit @ DJDavid98、ありがとう。 –

+0

コードを読みやすくするために、この種の字下げを使用するようにしてください。最終的なコードがどのように見えるかは分かりませんが、スタックオーバーフローについてはここでも良く見えます。人が醜いのでなければ、より多くの動機をもって質問に回答する傾向があります。 – SeinopSys

+0

@ DJDavid98 Yers私はあなたの言うことを確信しています。 –

答えて

4

は、私はあなたがjavascriptのも非同期chrome.storageのAPIで、シングルスレッドのコンテキスト内であるという事実を利用することによって、ロックせずに管理することができると思います。 chrome.storage.syncを使用していない限り、つまり、クラウドからの変更があってもなくてもかまいません。すべてのベットはオフになっていると思います。ローカルメモリ内のキューにあるコールバックとして消費者から

var getTask = (function() { 
    // Private list of requests. 
    var callbackQueue = []; 

    // This function is called when chrome.storage.local.set() has 
    // completed storing the updated task list. 
    var tasksWritten = function(nComplete) { 
    // Remove completed requests from the queue. 
    callbackQueue = callbackQueue.slice(nComplete); 

    // Handle any newly arrived requests. 
    if (callbackQueue.length) 
     chrome.storage.local.get('tasks', distributeTasks); 
    }; 

    // This function is called via chrome.storage.local.get() with the 
    // task list. 
    var distributeTasks = function(items) { 
    // Invoke callbacks with tasks. 
    var tasks = items['tasks']; 
    for (var i = 0; i < callbackQueue.length; ++i) 
     callbackQueue[i](tasks[i] || null); 

    // Update and store the task list. Pass the number of requests 
    // handled as an argument to the set() handler because the queue 
    // length may change by the time the handler is invoked. 
    chrome.storage.local.set(
     { 'tasks': tasks.slice(callbackQueue.length) }, 
     function() { 
     tasksWritten(callbackQueue.length); 
     } 
    ); 
    }; 

    // This is the public function task consumers call to get a new 
    // task. The task is returned via the callback argument. 
    return function(callback) { 
    if (callbackQueue.push(callback) === 1) 
     chrome.storage.local.get('tasks', distributeTasks); 
    }; 
})(); 

この店舗のタスク要求:

は、私が(カフ、ではないテスト、ないエラー処理をオフに書かれた)このような何かをするだろう。新しい要求が到着すると、コールバックがキューに追加され、タスクリストがフェッチされます。iffこれがキュー内の唯一の要求です。さもなければ、キューが既に処理されていると仮定できます(これは、実行リストがタスクリストにアクセスするための暗黙のロックです)。

タスクリストがフェッチされると、タスクは要求に分散されます。フェッチが完了するまでに複数のリクエストが到着した場合、複数のリクエストが存在する可能性があります。このコードは、タスクよりも多くのリクエストがある場合に、コールバックにnullを渡します。代わりに、より多くのタスクが到着するまでリクエストをブロックするには、未使用のコールバックを保持し、タスクが追加されたときにリクエスト処理を再開します。タスクを動的に生成し、消費することができる場合は、競合状態を防止する必要がありますが、ここでは示されません。

更新されたタスクリストが保存されるまで、タスクリストを再度読み取らないようにすることが重要です。これを達成するために、更新が完了するまで要求はキューから削除されません。その間に到着した要求を確実に処理する必要があります(chrome.storage.local.get()への呼び出しを短絡することは可能ですが、簡単にするためにこの方法で行いました)。

このアプローチは、できるだけ早く応答しながらタスクリストの更新を最小限に抑えるという意味でかなり効率的でなければなりません。明示的なロックまたは待機はありません。他のコンテキストでタスクコンシューマを使用している場合は、getTask()関数を呼び出すchrome.extensionメッセージハンドラを設定します。

関連する問題