Author: nbelaevski
Date: 2008-11-13 14:49:04 -0500 (Thu, 13 Nov 2008)
New Revision: 11153
Modified:
trunk/framework/impl/src/main/javascript/ajaxjsf/queue.js
Log:
queue.js script updated for the latest change request
Modified: trunk/framework/impl/src/main/javascript/ajaxjsf/queue.js
===================================================================
--- trunk/framework/impl/src/main/javascript/ajaxjsf/queue.js 2008-11-13 19:47:56 UTC (rev
11152)
+++ trunk/framework/impl/src/main/javascript/ajaxjsf/queue.js 2008-11-13 19:49:04 UTC (rev
11153)
@@ -3,12 +3,194 @@
A4J.AJAX._eventQueues = {};
+var extend = function(target, source) {
+ for (var property in source) {
+ target[property] = source[property];
+ }
+};
+
+var Pipeline = function(size, gate) {
+ this.size = size || -1;
+
+ this.gate = gate;
+ this.items = new Array();
+};
+
+extend(Pipeline.prototype, function() {
+
+ return {
+ submit: function() {
+ var data = this.items.shift();
+ if (data) {
+ this.request = data.submitWithCallback();
+ }
+ },
+
+ getSize: function() {
+ var size = this.items.length;
+
+ if (this.request) {
+ size++;
+ }
+
+ return size;
+ },
+
+ dropFirst: function() {
+ this.items.shift();
+ },
+
+ fireFirst: function() {
+ var data = this.items.shift();
+ if (data) {
+ data.submitWithoutCallback()
+ }
+ },
+
+ addEvent: function(data) {
+ if (!this.isFull()) {
+ this.items.push(data);
+
+ if (!this.request) {
+ this.submit();
+ }
+ } else {
+ //log error
+ }
+ },
+
+ submitNext: function() {
+ this.request = undefined;
+
+ if (this.getSize() > 0) {
+ this.submit();
+ } else {
+ this.gate.transferIfReady();
+ }
+ },
+
+ isFull: function() {
+ return this.getSize() == this.size;
+ },
+
+ isEmpty: function() {
+ return this.getSize() == 0;
+ }
+ }
+}());
+
+var Gate = function() {
+ this.eventsCounter = 0;
+};
+
+extend(Gate.prototype, {
+
+ stopRequestDelay: function () {
+ if (this.timer) {
+ clearTimeout(this.timer);
+ this.timer = undefined;
+ }
+ },
+
+ resetRequestDelay: function() {
+ this.delayPassed = false;
+
+ this.stopRequestDelay();
+ this.startRequestDelay();
+ },
+
+ startRequestDelay: function() {
+ var delay = this.data.getRequestDelay();
+ if (delay) {
+ var _this = this;
+ this.timer = setTimeout(function() {
+ try {
+ _this.transferIfPipelineEmpty();
+ _this.timer = undefined;
+ } finally {
+ _this = undefined;
+ }
+ }, delay);
+ } else {
+ this.transferIfPipelineEmpty();
+ }
+ },
+
+ transferIfPipelineEmpty: function() {
+ if (this.pipeline.isEmpty()) {
+ this.pipeline.addEvent(this.pop());
+ } else {
+ this.delayPassed = true;
+ }
+ },
+
+ transferIfReady: function() {
+ if (this.delayPassed) {
+ this.pipeline.addEvent(this.pop());
+ }
+ },
+
+ pop: function() {
+ var data = this.data;
+ this.data = undefined;
+
+ this.eventsCounter = 0;
+ this.requestId = undefined;
+ this.delayPassed = false;
+
+ return data;
+ },
+
+ push: function(data) {
+ var requestId = data.getRequestId();
+
+ if (this.requestId == requestId) {
+ this.data = data;
+ data.setEventsCounter(++this.eventsCounter);
+
+ this.resetRequestDelay();
+ } else {
+ if (this.data) {
+ this.stopRequestDelay();
+ this.pipeline.addEvent(this.pop());
+ }
+
+ if (this.pipeline.isFull()) {
+ //special handling for size = 1 queue
+
+ var behavior = data.queue.getSizeExceededBehavior();
+ if (behavior == 'dropNew') {
+ return;
+ } else if (behavior == 'fireNew') {
+ data.submitWithoutCallback();
+ return;
+ } else if (behavior == 'fireNext') {
+ this.pipeline.fireFirst();
+ } else if (behavior == 'dropNext') {
+ this.pipeline.dropFirst();
+ }
+
+ }
+
+ this.data = data;
+ this.requestId = requestId;
+ this.startRequestDelay();
+ }
+
+ },
+});
+
+
//queue constructor
A4J.AJAX.EventQueue = function(name, queueOptions, requestOptions) {
this.name = name;
this.queueOptions = queueOptions || {};
this.requestOptions = requestOptions || {};
+ this.gate = new Gate();
+ this.pipeline = new Pipeline(this.queueOptions.size, this.gate);
+ this.gate.pipeline = this.pipeline;
+
this.queue = new Array();
};
@@ -80,6 +262,104 @@
A4J.AJAX.EventQueue.prototype = function() {
+
+ /*
+ * Queue: {
+ * pop: {
+ * pop();
+ * barrier.unlock();
+ *
+ * if (!empty) {
+ * submit();
+ * } else {
+ * barrier.transferIfReady();
+ * }
+ * },
+ *
+ * push: {
+ * if (full) {
+ * throw e;
+ * }
+ *
+ * push();
+ *
+ * if (full) {
+ * barrier.lock();
+ * }
+ *
+ * if (!submitted) {
+ * submit();
+ * }
+ * }
+ *
+ * submit: {
+ * submit();
+ * }
+ *
+ * }
+ *
+ * Barrier: {
+ * match: {
+ * //not matches if empty
+ * }
+ *
+ * push: {
+ * if (match()) {
+ * //queue size stays the same
+ *
+ * assign();
+ * increaseCounter();
+ *
+ * //reset can do immediate transfer
+ * clearTimeout();
+ * setTimeout(transferIfQueueEmpty())
+ * } else {
+ * //queue size increased by one
+ *
+ * if (!empty) {
+ * clearTimeout();
+ * delayPassed = true;
+ * transfer();
+ * }
+ *
+ * if (locked) {
+ * //special unlock case when size = 1
+ * unlock();
+ * }
+ *
+ * assign();
+ * setTimeout(transferIfQueueEmpty())
+ * }
+ * }
+ *
+ * pop: {
+ * applyCounter();
+ * resetCounter();
+ * delayPassed = false;
+ * empty = true;
+ * }
+ *
+ * transfer: {
+ * queue.push(pop());
+ * }
+ *
+ * transferIfQueueEmpty: {
+ * if (queue.isEmpty()) {
+ * transfer();
+ * } else {
+ * delayPassed = true;
+ * }
+ * }
+ *
+ * transferIfReady: {
+ * if (delayPassed) {
+ * transfer();
+ * }
+ * }
+ * }
+ */
+
+
var EventQueueData = function(queue, query, options) {
this.queue = queue;
this.query = query;
@@ -88,51 +368,80 @@
this.eventsCount = 1;
};
- EventQueueData.prototype.setEventData = function(query, options) {
- this.query = query;
- this.options = options;
- };
-
- EventQueueData.prototype.increaseEventCounter = function() {
- this.eventsCount++;
- };
-
- EventQueueData.prototype.executeDelay = function() {
- var delay = this.options.requestDelay;
- LOG.debug("Queue will wait " + (delay || 0) + "ms before submit");
-
- if (delay) {
- var _this = this;
+ extend(EventQueueData.prototype, {
+ submitWithCallback: function() {
+ this.query.appendParameter("AJAX:EVENTS_COUNT", this.eventsCount);
- this.timerId = setTimeout(function() {
- try {
- _this.delayPassed = true;
- _this.queue.submit();
- } finally {
- _this = undefined;
- }
- }, delay);
- } else {
- this.delayPassed = true;
- this.queue.submit();
+ var request = A4J.AJAX.SubmitQuery(this.query, this.options)
+ request.queue = this.queue;
+
+ return request;
+ },
+
+ submitWithoutCallback: function() {
+ this.query.appendParameter("AJAX:EVENTS_COUNT", this.eventsCount);
+ return A4J.AJAX.SubmitQuery(this.query, this.options)
+ },
+
+ getRequestId: function() {
+ return this.options.requestId;
+ },
+
+ getRequestDelay: function() {
+ return this.options.requestDelay;
+ },
+
+ setEventsCounter: function(count) {
+ this.eventsCount = count;
}
- };
+ });
- EventQueueData.prototype.abortDelay = function() {
- if (this.timerId) {
- clearTimeout(this.timerId);
- this.timerId = undefined;
- }
-
- this.delayPassed = false;
- };
-
- EventQueueData.prototype.submit = function() {
- this.query.appendParameter("AJAX:EVENTS_COUNT", this.eventsCount);
-
- return A4J.AJAX.SubmitQuery(this.query, this.options)
- };
+// EventQueueData.prototype.setEventData = function(query, options) {
+// this.query = query;
+// this.options = options;
+// };
+//
+// EventQueueData.prototype.increaseEventCounter = function() {
+// this.eventsCount++;
+// };
+//
+// EventQueueData.prototype.executeDelay = function() {
+// var delay = this.options.requestDelay;
+// LOG.debug("Queue will wait " + (delay || 0) + "ms before
submit");
+//
+// if (delay) {
+// var _this = this;
+//
+// this.timerId = setTimeout(function() {
+// try {
+// _this.delayPassed = true;
+// _this.queue.submit();
+// } finally {
+// _this = undefined;
+// }
+// }, delay);
+// } else {
+// this.delayPassed = true;
+// this.queue.submit();
+// }
+// };
+//
+// EventQueueData.prototype.abortDelay = function() {
+// if (this.timerId) {
+// clearTimeout(this.timerId);
+//
+// this.timerId = undefined;
+// }
+//
+// this.delayPassed = false;
+// };
+//
+// EventQueueData.prototype.submit = function() {
+// this.query.appendParameter("AJAX:EVENTS_COUNT", this.eventsCount);
+//
+// return A4J.AJAX.SubmitQuery(this.query, this.options)
+// };
var extendOptions = function(options) {
var opts = {};
@@ -221,62 +530,69 @@
return function(query, opts) {
var options = extendOptions.call(this, opts);
+ var queueData = new EventQueueData(this, query, options);
- //TODO add processing for ignoreDupResponse
-
- var queueData;
-
- var requestId = options.requestId;
+ this.gate.push(queueData);
- if (this.queue.length == 0 || requestId != this._requestId) {
- queueData = new EventQueueData(this, query, options);
-
- if (this.getQueueSize() == this.queue.length) {
- var oversizeBehavior = this.getSizeExceededBehavior();
- if ('dropNext' == oversizeBehavior) {
- removeFirst.call(this);
- addToQueue.call(this, queueData, requestId);
- } else if ('fireNext' == oversizeBehavior) {
- var firstQueueData = removeFirst.call(this);
- if (firstQueueData) {
- firstQueueData.submit();
- }
- addToQueue.call(this, queueData, requestId);
- } else if ('dropNew' == oversizeBehavior) {
- dropNew.call(this);
- } else if ('fireNew' == oversizeBehavior) {
- fireNew.call(this, queueData);
- }
- } else {
- addToQueue.call(this, queueData, requestId);
- }
- } else {
- queueData = this.queue[this.queue.length - 1];
- queueData.setEventData(query, options);
- queueData.increaseEventCounter();
-
- queueData.abortDelay();
- queueData.executeDelay();
-
- LOG.debug("Similar request already in queue '" + this.name +
"'");
- }
+// var options = extendOptions.call(this, opts);
+//
+// //TODO add processing for ignoreDupResponse
+//
+// var queueData;
+//
+// var requestId = options.requestId;
+//
+// if (this.queue.length == 0 || requestId != this._requestId) {
+// queueData = new EventQueueData(this, query, options);
+//
+// if (this.getQueueSize() == this.queue.length) {
+// var oversizeBehavior = this.getSizeExceededBehavior();
+// if ('dropNext' == oversizeBehavior) {
+// removeFirst.call(this);
+// addToQueue.call(this, queueData, requestId);
+// } else if ('fireNext' == oversizeBehavior) {
+// var firstQueueData = removeFirst.call(this);
+// if (firstQueueData) {
+// firstQueueData.submit();
+// }
+// addToQueue.call(this, queueData, requestId);
+// } else if ('dropNew' == oversizeBehavior) {
+// dropNew.call(this);
+// } else if ('fireNew' == oversizeBehavior) {
+// fireNew.call(this, queueData);
+// }
+// } else {
+// addToQueue.call(this, queueData, requestId);
+// }
+// } else {
+// queueData = this.queue[this.queue.length - 1];
+// queueData.setEventData(query, options);
+// queueData.increaseEventCounter();
+//
+// queueData.abortDelay();
+// queueData.executeDelay();
+//
+// LOG.debug("Similar request already in queue '" + this.name +
"'");
+// }
}
}(),
pop: function() {
- this.request = undefined;
+ this.pipeline.submitNext()
- if (this.queue.length == 0) {
- LOG.debug("After request: queue '" + this.name + "' is empty
now");
-
- if (this._transient) {
- LOG.debug("Deleting transient queue '" + this.name + "' from
queues registry");
- A4J.AJAX.EventQueue.removeQueue(this.name);
- }
- } else {
- LOG.debug("After request: queue not empty, processing next event in queue
'" + this.name + "'");
- this.submit();
- }
+// this.request = undefined;
+//
+// if (this.queue.length == 0) {
+// LOG.debug("After request: queue '" + this.name + "' is empty
now");
+//
+// if (this._transient) {
+// LOG.debug("Deleting transient queue '" + this.name + "'
from queues registry");
+// A4J.AJAX.EventQueue.removeQueue(this.name);
+// }
+// } else {
+// LOG.debug("After request: queue not empty, processing next event in queue
'" + this.name + "'");
+// this.submit();
+// }
}
}
}();