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