1 /* ************************************************************************
3 qooxdoo - the new era of web development
8 2004-2007 1&1 Internet AG, Germany, http://www.1and1.org
12 LGPL: http://www.gnu.org/licenses/lgpl.html
13 EPL: http://www.eclipse.org/org/documents/epl-v10.php
14 See the LICENSE file in the project's top-level directory for details.
17 * Sebastian Werner (wpbasti)
18 * Andreas Ecker (ecker)
19 * Derrell Lipman (derrell)
21 ************************************************************************ */
23 /* ************************************************************************
27 ************************************************************************ */
30 * Handles scheduling of requests to be sent to a server.
32 * This class is a singleton and is used by qx.io.remote.Request to schedule its
33 * requests. It should not be used directly.
35 qx.OO.defineClass("qx.io.remote.RequestQueue", qx.core.Target,
38 qx.core.Target.call(this);
43 this._totalRequests = 0;
46 this._timer = new qx.client.Timer(500);
47 this._timer.addEventListener("interval", this._oninterval, this);
54 ---------------------------------------------------------------------------
56 ---------------------------------------------------------------------------
62 qx.OO.addProperty({ name : "maxTotalRequests", type : "number" });
65 * Maximum number of parallel requests.
67 qx.OO.addProperty({ name : "maxConcurrentRequests", type : "number", defaultValue : 3 });
70 * Default timeout for remote requests in milliseconds.
72 qx.OO.addProperty({ name : "defaultTimeout", type : "number", defaultValue : 5000 });
80 ---------------------------------------------------------------------------
82 ---------------------------------------------------------------------------
85 qx.Proto._debug = function()
88 var vText = this._active.length + "/" + (this._queue.length+this._active.length);
90 if (qx.Settings.getValueOfClass("qx.io.remote.Exchange", "enableDebug"))
92 this.debug("Progress: " + vText);
93 window.status = "Request-Queue Progress: " + vText;
97 qx.Proto._check = function()
102 // Check queues and stop timer if not needed anymore
103 if (this._active.length == 0 && this._queue.length == 0) {
107 // Checking if enabled
108 if (!this.getEnabled()) {
112 // Checking active queue fill
113 if (this._active.length >= this.getMaxConcurrentRequests() || this._queue.length == 0) {
117 // Checking number of total requests
118 if (this.getMaxTotalRequests() != null && this._totalRequests >= this.getMaxTotalRequests()) {
122 var vRequest = this._queue.shift();
123 var vTransport = new qx.io.remote.Exchange(vRequest);
126 this._totalRequests++;
128 // Add to active queue
129 this._active.push(vTransport);
134 // Establish event connection between qx.io.remote.Exchange instance and qx.io.remote.Request
135 vTransport.addEventListener("sending", vRequest._onsending, vRequest);
136 vTransport.addEventListener("receiving", vRequest._onreceiving, vRequest);
137 vTransport.addEventListener("completed", vRequest._oncompleted, vRequest);
138 vTransport.addEventListener("aborted", vRequest._onaborted, vRequest);
139 vTransport.addEventListener("timeout", vRequest._ontimeout, vRequest);
140 vTransport.addEventListener("failed", vRequest._onfailed, vRequest);
142 // Establish event connection between qx.io.remote.Exchange and me.
143 vTransport.addEventListener("sending", this._onsending, this);
144 vTransport.addEventListener("completed", this._oncompleted, this);
145 vTransport.addEventListener("aborted", this._oncompleted, this);
146 vTransport.addEventListener("timeout", this._oncompleted, this);
147 vTransport.addEventListener("failed", this._oncompleted, this);
149 // Store send timestamp
150 vTransport._start = (new Date).valueOf();
156 if (this._queue.length > 0) {
161 qx.Proto._remove = function(vTransport)
163 var vRequest = vTransport.getRequest();
165 // Destruct event connection between qx.io.remote.Exchange instance and qx.io.remote.Request
166 vTransport.removeEventListener("sending", vRequest._onsending, vRequest);
167 vTransport.removeEventListener("receiving", vRequest._onreceiving, vRequest);
168 vTransport.removeEventListener("completed", vRequest._oncompleted, vRequest);
169 vTransport.removeEventListener("aborted", vRequest._onaborted, vRequest);
170 vTransport.removeEventListener("timeout", vRequest._ontimeout, vRequest);
171 vTransport.removeEventListener("failed", vRequest._onfailed, vRequest);
173 // Destruct event connection between qx.io.remote.Exchange and me.
174 vTransport.removeEventListener("sending", this._onsending, this);
175 vTransport.removeEventListener("completed", this._oncompleted, this);
176 vTransport.removeEventListener("aborted", this._oncompleted, this);
177 vTransport.removeEventListener("timeout", this._oncompleted, this);
178 vTransport.removeEventListener("failed", this._oncompleted, this);
180 // Remove from active transports
181 qx.lang.Array.remove(this._active, vTransport);
183 // Dispose transport object
184 vTransport.dispose();
197 ---------------------------------------------------------------------------
199 ---------------------------------------------------------------------------
202 qx.Proto._activeCount = 0;
204 qx.Proto._onsending = function(e)
206 if (qx.Settings.getValueOfClass("qx.io.remote.Exchange", "enableDebug"))
209 e.getTarget()._counted = true;
211 this.debug("ActiveCount: " + this._activeCount);
215 qx.Proto._oncompleted = function(e)
217 if (qx.Settings.getValueOfClass("qx.io.remote.Exchange", "enableDebug"))
219 if (e.getTarget()._counted)
222 this.debug("ActiveCount: " + this._activeCount);
226 this._remove(e.getTarget());
236 ---------------------------------------------------------------------------
238 ---------------------------------------------------------------------------
241 qx.Proto._oninterval = function(e)
243 var vActive = this._active;
245 if (vActive.length == 0) {
249 var vCurrent = (new Date).valueOf();
252 var vDefaultTimeout = this.getDefaultTimeout();
256 for (var i=vActive.length-1; i>=0; i--)
258 vTransport = vActive[i];
259 vRequest = vTransport.getRequest();
260 if (vRequest.isAsynchronous()) {
261 vTimeout = vRequest.getTimeout();
263 // if timer is disabled...
269 if (vTimeout == null) {
270 vTimeout = vDefaultTimeout;
273 vTime = vCurrent - vTransport._start;
275 if (vTime > vTimeout)
277 this.warn("Timeout: transport " + vTransport.toHashCode());
278 this.warn(vTime + "ms > " + vTimeout + "ms");
279 vTransport.timeout();
289 ---------------------------------------------------------------------------
291 ---------------------------------------------------------------------------
294 qx.Proto._modifyEnabled = function(propValue, propOldValue, propData)
300 this._timer.setEnabled(propValue);
312 ---------------------------------------------------------------------------
314 ---------------------------------------------------------------------------
317 Add the request to the pending requests queue.
319 qx.Proto.add = function(vRequest)
321 vRequest.setState("queued");
323 this._queue.push(vRequest);
326 if (this.getEnabled()) {
332 Remove the request from the pending requests queue.
334 The underlying transport of the request is forced into the aborted
335 state ("aborted") and listeners of the "aborted"
336 signal are notified about the event. If the request isn't in the
337 pending requests queue, this method is a noop.
339 qx.Proto.abort = function(vRequest)
341 var vTransport = vRequest.getTransport();
347 else if (qx.lang.Array.contains(this._queue, vRequest))
349 qx.lang.Array.remove(this._queue, vRequest);
360 ---------------------------------------------------------------------------
362 ---------------------------------------------------------------------------
368 qx.Proto.dispose = function()
370 if (this.getDisposed()) {
376 for (var i=0, a=this._active, l=a.length; i<l; i++) {
385 this._timer.removeEventListener("interval", this._oninterval, this);
391 return qx.core.Target.prototype.dispose.call(this);
401 ---------------------------------------------------------------------------
402 DEFER SINGLETON INSTANCE
403 ---------------------------------------------------------------------------
407 * Singleton Instance Getter
409 qx.Class.getInstance = qx.lang.Function.returnInstance;