8
  1. Qualcosa richiede un'attività
  2. Qualcos'altro estrae l'elenco delle attività dalla memoria e controlla se ci sono attività lì.
  3. Se ci sono attività che rimuove una e la "lista delle attività" più piccola viene rimessa in magazzino.

Tra i punti 2 e 3 una gara condizione di può verificarsi se si verificano più richieste, e lo stesso compito sarà servita due volte.Il modo migliore per prevenire le condizioni di gara in più chiamate API chrome.storage?

La risoluzione corretta per "bloccare" la "tabella delle attività" mentre una singola attività è "estratta", per evitare altre richieste?

Qual è la soluzione con il minor impatto sulle prestazioni, come il ritardo di esecuzione, e come dovrebbe essere implementata in javascript con chrome.storage API?

Alcuni codice per esempio:

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, grazie. –

+0

Dovresti provare a usare questo tipo di indentazione per rendere il codice più leggibile. Anche se non è come appare il codice finale, sembra ancora meglio qui su Stack Overflow, e le persone tendono a rispondere alla domanda con più motivazione se non sono brutte. – SeinopSys

+0

@ DJDavid98 Yers Sono convinto di quello che dici. –

risposta

4

Credo è possibile gestire senza serratura approfittando del fatto che JavaScript è thread singolo in un contesto, anche con l'API chrome.storage asincrono. Finché non stai usando chrome.storage.sync, questo è - se ci possono essere o meno modifiche dal cloud, penso che tutte le scommesse siano disattivate.

vorrei fare qualcosa di simile (scritto a braccio, non testato, nessuna gestione degli errori):

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); 
    }; 
})(); 

Questo compito memorizza le richieste da parte dei consumatori come callback in una coda nella memoria locale. Quando arriva una nuova richiesta, il callback viene aggiunto alla coda e l'elenco delle attività viene recuperato iff questa è l'unica richiesta in coda. Altrimenti, possiamo supporre che la coda sia già in fase di elaborazione (questo è un blocco implicito che consente a un solo filone di esecuzione di accedere all'elenco delle attività).

Quando l'elenco delle attività viene recuperato, le attività vengono distribuite alle richieste. Nota che potrebbero esserci più di una richiesta se ne sono arrivate altre prima che il recupero sia completato. Questo codice passa semplicemente null a un callback se ci sono più richieste che attività. Per bloccare invece le richieste fino all'arrivo di altre attività, tieni i callback non utilizzati e riavvia l'elaborazione delle richieste quando vengono aggiunte le attività. Se le attività possono essere generate dinamicamente e consumate, ricorda che le condizioni di gara dovranno essere prevenute anche qui, ma non sono mostrate qui.

È importante evitare di leggere nuovamente l'elenco delle attività finché non viene memorizzato l'elenco delle attività aggiornate. Per fare ciò, le richieste non vengono rimosse dalla coda fino al completamento dell'aggiornamento. Quindi dobbiamo assicurarci di elaborare tutte le richieste che sono arrivate nel frattempo (è possibile cortocircuitare la chiamata a chrome.storage.local.get() ma l'ho fatto in questo modo per semplicità).

Questo approccio dovrebbe essere abbastanza efficiente nel senso che dovrebbe ridurre al minimo gli aggiornamenti all'elenco delle attività mentre risponde nel più breve tempo possibile. Non c'è blocco o attesa esplicita. Se si hanno utenti di attività in altri contesti, impostare un gestore di messaggi chrome.extension che chiama la funzione getTask().

Problemi correlati