mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-25 00:02:41 +01:00
116 lines
2.3 KiB
JavaScript
116 lines
2.3 KiB
JavaScript
|
/**
|
||
|
* @provides javelin-router
|
||
|
* @requires javelin-install
|
||
|
* javelin-util
|
||
|
* @javelin
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* Route requests. Primarily, this class provides a quality-of-service
|
||
|
* priority queue so large numbers of background loading tasks don't block
|
||
|
* interactive requests.
|
||
|
*/
|
||
|
JX.install('Router', {
|
||
|
|
||
|
construct: function() {
|
||
|
this._queue = [];
|
||
|
},
|
||
|
|
||
|
events: ['queue', 'start', 'done'],
|
||
|
|
||
|
members: {
|
||
|
_queue: null,
|
||
|
_active: 0,
|
||
|
_limit: 5,
|
||
|
|
||
|
queue: function(routable) {
|
||
|
this._queue.push(routable);
|
||
|
|
||
|
this.invoke('queue', routable);
|
||
|
this._update();
|
||
|
},
|
||
|
|
||
|
getRoutableByKey: function(key) {
|
||
|
for (var ii = 0; ii < this._queue.length; ii++) {
|
||
|
if (this._queue[ii].getKey() == key) {
|
||
|
return this._queue[ii];
|
||
|
}
|
||
|
}
|
||
|
return null;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Start new requests if we have slots free for them.
|
||
|
*/
|
||
|
_update: function() {
|
||
|
var active = this._active;
|
||
|
var limit = this._limit;
|
||
|
|
||
|
if (active >= limit) {
|
||
|
// If we're already at the request limit, we can't add any more
|
||
|
// requests.
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// If we only have one free slot, we reserve it for a request with
|
||
|
// at least priority 1000.
|
||
|
var minimum;
|
||
|
if ((active + 1) == limit) {
|
||
|
minimum = 1000;
|
||
|
} else {
|
||
|
minimum = 0;
|
||
|
}
|
||
|
|
||
|
var idx = this._getNextRoutable(minimum);
|
||
|
if (idx === null) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var routable = this._queue[idx];
|
||
|
this._queue.splice(idx, 1);
|
||
|
|
||
|
|
||
|
routable.listen('done', JX.bind(this, this._done, routable));
|
||
|
|
||
|
this._active++;
|
||
|
routable.start();
|
||
|
this.invoke('start', routable);
|
||
|
|
||
|
this._update();
|
||
|
},
|
||
|
|
||
|
_done: function(routable) {
|
||
|
this._active--;
|
||
|
this.invoke('done', routable);
|
||
|
|
||
|
this._update();
|
||
|
},
|
||
|
|
||
|
_getNextRoutable: function(minimum) {
|
||
|
var best = (minimum - 1);
|
||
|
|
||
|
var routable = null;
|
||
|
for (var ii = 0; ii < this._queue.length; ii++) {
|
||
|
var priority = this._queue[ii].getPriority();
|
||
|
if (priority > best) {
|
||
|
best = priority;
|
||
|
routable = ii;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return routable;
|
||
|
}
|
||
|
|
||
|
},
|
||
|
|
||
|
statics: {
|
||
|
_instance: null,
|
||
|
getInstance: function() {
|
||
|
if (!JX.Router._instance) {
|
||
|
JX.Router._instance = new JX.Router();
|
||
|
}
|
||
|
return JX.Router._instance;
|
||
|
}
|
||
|
}
|
||
|
});
|