/** * use * 0) set max parallel concurrency * $$.sync.setMaxParallel(n) * 1) prepare a packet * {data: {...}, parallel: true|false, callback: , connector: ''} * 2) enqueue the packet * $$.sync.enqueue(packet, true(enable immediate transport of packet)|false(disable immediate transport, enqueue only)) * 3) flush queue when immediate transport is disabled * $$.sync.flush() */ (function(undefined) { /* local var and method */ var version = '0.0'; var queue = []; // coda dei pacchetti da trasmettere su una linea di comunicazione seriale var travelPck = {}; // pacchetto estratto dalla coda e pronto da inviare in uno schema di trasmissione serializzata var carrier = true; // portante del canale di comunicazione seriale var queueParallel = []; // coda dei pachetti da trasmettere su una linea di comunicazione parallela var travelPckParallel = []; // pacchetti estratto dalla coda e pronti da inviare in uno schema di trasmissione parallela var carrierParallel = 0; // numero di portanti occupate per invio parallelo dei pacchetti var MAXPARALLEL = 0; // numero massimo di invii paralleli (impostare 0 per non avere un limite) var flushCallback = null; /** * spool delle code di invio */ var spool = function() { spoolSerial(); spoolParallel(); } /** * spool della coda seriale */ var spoolSerial = function() { // le seguenti due istruzioni andrebbero eseguite in sezione critica if (!carrier) return; // controllo la presenza della portante per inviare il pacchetto carrier = false; // occupo il canale di comunicazione if (queue.length > 0) { // se ci sono pacchetti in coda estraggo l'ultmo travelPck = queue.pop(); // estraggo l'ultimo transport(); // eseguo la trasmissione del pacchetto } else { carrier = true; // nessun pacchetto in coda; libero il canale di comunicazione if (queue.length > 0) { // se ci sono pacchetti in coda rieseguo lo spool spoolSerial(); } else { if(typeof flushCallback == 'function') flushCallback(); } } } /** * spool della coda parallela */ var spoolParallel = function() { if (MAXPARALLEL > 0 && carrierParallel >= MAXPARALLEL) return; // se le portanti parallele sono già tutte occupate postpongo l'invio carrierParallel++; // occupo uno dei canali di comunicazione parallela if (queueParallel.length > 0) { // se ci sono pacchetti in coda estraggo l'ultmo var pk = queueParallel.pop(); // estraggo l'ultimo transportParallel(pk); // eseguo la trasmissione del pacchetto spoolParallel(); // rieseguo lo spool parallello } else { carrierParallel--; // libero il canale if (queueParallel.length > 0) { // se ci sono pacchetti in coda rieseguo lo spool spoolParallel(); } } } /** * invio del pacchetto sulla linea seriale */ var transport = function() { $$.debug.log('info', 'jFSync: start transport!'); $.ajax({ url: travelPck.connector, type: 'POST', dataType: 'json', data: travelPck.data }).done(function(data) { $$.debug.log('info', 'jFSync: end transport done!'); if (typeof travelPck.callback == 'function') { travelPck.callback(data); } }).fail(function(jqXHR, textStatus, errorThrown ) { $$.debug.log('info', 'jFSync: end transport fail!'); alert('FAIL: ' + textStatus + ' - ' + errorThrown); }).always(function() { carrier = true; // libero il canale e rieseguo lo spool spool(); }); } /** * invio del pacchetto sulla linea parallela */ var transportParallel = function(packet) { $.ajax({ url: packet.connector, type: 'POST', dataType: 'json', data: packet.data }).done(function(data) { if (typeof packet.callback == 'function') { packet.callback(data); } carrierParallel--; // libero uno dei canali paralleli e rieseguo lo spool spool(); }).fail(function(jqXHR, textStatus, errorThrown ) { alert('FAIL: ' + textStatus + ' - ' + errorThrown); carrierParallel--; // libero uno dei canali paralleli e rieseguo lo spool spool(); }).always(function() { }); } /* object prototype */ /* public method and attribute */ /** * serialize ajax call */ $$.sync = {}; /** * imposta il numero massimo di pacchetti inviabili parallelamente * * @param massimo int numero massimo di pacchetti parallelizzabili */ $$.sync.setMaxParallel = function(massimo) { MAXPARALLEL = massimo?massimo:0; } /** * inserisce un pacchetto in coda ed esegue lo spool * @param packet object { * connector string mandatory url sul server, * parallel boolean optional true=attiva comunicazione parallela, * data object optional request al connector, * callback function optional funzione di callback * } * @param flush boolean (true)|false if true flush the queues */ $$.sync.enqueue = function(packet, flush) { if (typeof packet != 'object') return; if(typeof flush === 'undefined') flush = true; if (typeof packet.parallel == 'boolean' && packet.parallel) { queueParallel.unshift(packet); // inserisco il pacchetto nella coda parallela } else { queue.unshift(packet); // inserisco il pacchetto nella coda seriale } if(flush) spool(); // eseguo lo spool per inviare i pacchetti in coda } /** * esegue lo spool dei pacchetti in coda */ $$.sync.flush = function(callback) { flushCallback = typeof callback == 'function'?callback:null; spool(); } })();