mirror of
https://github.com/EGroupware/egroupware.git
synced 2025-08-19 04:46:42 +02:00
Limit concurrent server requests from nextmatch to 5, wait others until the pending ones get answered
This commit is contained in:
@@ -36,6 +36,9 @@ var ET2_DATAVIEW_STEPSIZE = 50;
|
|||||||
*/
|
*/
|
||||||
var et2_dataview_controller = (function(){ "use strict"; return Class.extend({
|
var et2_dataview_controller = (function(){ "use strict"; return Class.extend({
|
||||||
|
|
||||||
|
// Maximum concurrent data requests. Additional ones are held in the queue.
|
||||||
|
CONCURRENT_REQUESTS: 5,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor of the et2_dataview_controller, connects to the grid
|
* Constructor of the et2_dataview_controller, connects to the grid
|
||||||
* callback.
|
* callback.
|
||||||
@@ -75,10 +78,14 @@ var et2_dataview_controller = (function(){ "use strict"; return Class.extend({
|
|||||||
// Timer used for queing fetch requests
|
// Timer used for queing fetch requests
|
||||||
this._queueTimer = null;
|
this._queueTimer = null;
|
||||||
|
|
||||||
// Array which contains all currently queued indices in the form of
|
// Array which contains all currently queued row indices in the form of
|
||||||
// an associative array
|
// an associative array
|
||||||
this._queue = {};
|
this._queue = {};
|
||||||
|
|
||||||
|
// Current concurrent requests we have
|
||||||
|
this._request_queue = [];
|
||||||
|
this._request_timeout = 0;
|
||||||
|
|
||||||
// Register the dataFetch callback
|
// Register the dataFetch callback
|
||||||
this._grid.setDataCallback(this._gridCallback, this);
|
this._grid.setDataCallback(this._gridCallback, this);
|
||||||
|
|
||||||
@@ -173,6 +180,7 @@ var et2_dataview_controller = (function(){ "use strict"; return Class.extend({
|
|||||||
{
|
{
|
||||||
range.top = range.bottom = 0;
|
range.top = range.bottom = 0;
|
||||||
}
|
}
|
||||||
|
this._request_queue = [];
|
||||||
|
|
||||||
// Require that range from the server
|
// Require that range from the server
|
||||||
this._queueFetch(et2_bounds(range.top, clear ? 0 : range.bottom + 1), 0, true);
|
this._queueFetch(et2_bounds(range.top, clear ? 0 : range.bottom + 1), 0, true);
|
||||||
@@ -190,9 +198,13 @@ var et2_dataview_controller = (function(){ "use strict"; return Class.extend({
|
|||||||
// Clear the grid
|
// Clear the grid
|
||||||
this._grid.clear();
|
this._grid.clear();
|
||||||
|
|
||||||
// Clear the queue
|
// Clear the row queue
|
||||||
this._queue = {};
|
this._queue = {};
|
||||||
|
|
||||||
|
// Reset the request queue
|
||||||
|
this._request_queue = [];
|
||||||
|
this._request_timeout = 0;
|
||||||
|
|
||||||
// Update the data
|
// Update the data
|
||||||
this.update();
|
this.update();
|
||||||
},
|
},
|
||||||
@@ -481,6 +493,17 @@ var et2_dataview_controller = (function(){ "use strict"; return Class.extend({
|
|||||||
// Clear any still existing timer
|
// Clear any still existing timer
|
||||||
this._clearTimer();
|
this._clearTimer();
|
||||||
|
|
||||||
|
if(this._request_queue.length >= this.CONCURRENT_REQUESTS)
|
||||||
|
{
|
||||||
|
// Too many requests, wait until later
|
||||||
|
var self = this;
|
||||||
|
this._queueTimer = window.setTimeout(function () {
|
||||||
|
self._flushQueue(_isUpdate);
|
||||||
|
// Try again with increasing delay, to a max of 30s
|
||||||
|
}, Math.min(30000,ET2_DATAVIEW_FETCH_TIMEOUT*Math.pow( 2, this._request_timeout++)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Mark all elements in a radius of ET2_DATAVIEW_STEPSIZE
|
// Mark all elements in a radius of ET2_DATAVIEW_STEPSIZE
|
||||||
var marked = {};
|
var marked = {};
|
||||||
var r = _isUpdate ? 0 : Math.floor(ET2_DATAVIEW_STEPSIZE / 2);
|
var r = _isUpdate ? 0 : Math.floor(ET2_DATAVIEW_STEPSIZE / 2);
|
||||||
@@ -577,10 +600,61 @@ var et2_dataview_controller = (function(){ "use strict"; return Class.extend({
|
|||||||
ctx.prefix = this.dataStorePrefix;
|
ctx.prefix = this.dataStorePrefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call the callback
|
this._queueRequest(query, ctx);
|
||||||
this._dataProvider.dataFetch(query, this._fetchCallback, ctx);
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queue a request for data
|
||||||
|
* @param {Object} query
|
||||||
|
* @param {Object} ctx
|
||||||
|
*/
|
||||||
|
_queueRequest: function _queueRequest(query, ctx)
|
||||||
|
{
|
||||||
|
this._request_queue.push({
|
||||||
|
query: query,
|
||||||
|
context: ctx,
|
||||||
|
status: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
this._fetchQueuedRequest();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch data for a queued request, subject to rate limit
|
||||||
|
*/
|
||||||
|
_fetchQueuedRequest: function _fetchQueuedRequest()
|
||||||
|
{
|
||||||
|
// Check to see if there's room
|
||||||
|
var count = 0;
|
||||||
|
for (var i = 0; i < this._request_queue.length; i++)
|
||||||
|
{
|
||||||
|
if(this._request_queue[i].status > 0) count++;
|
||||||
|
}
|
||||||
|
// Too many requests, will try again after response is received
|
||||||
|
if(count >= this.CONCURRENT_REQUESTS || this._request_queue.length === 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Reset timeout timer
|
||||||
|
this._request_timeout = 0;
|
||||||
|
|
||||||
|
// The most recent is the one the user's most interested in
|
||||||
|
var request = null;
|
||||||
|
for(var i = this._request_queue.length - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if(this._request_queue[i].status == 0)
|
||||||
|
{
|
||||||
|
request = this._request_queue[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(request == null) return;
|
||||||
|
|
||||||
|
request.status = 1;
|
||||||
|
|
||||||
|
// Call the callback
|
||||||
|
this._dataProvider.dataFetch(request.query, this._fetchCallback, request.context);
|
||||||
},
|
},
|
||||||
|
|
||||||
_clearTimer: function () {
|
_clearTimer: function () {
|
||||||
@@ -846,6 +920,18 @@ var et2_dataview_controller = (function(){ "use strict"; return Class.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_fetchCallback: function (_response) {
|
_fetchCallback: function (_response) {
|
||||||
|
// Remove answered request from queue
|
||||||
|
var request = null;
|
||||||
|
for(var i = 0; i < this.self._request_queue.length; i++)
|
||||||
|
{
|
||||||
|
if(this.self._request_queue[i].context == this)
|
||||||
|
{
|
||||||
|
request = this.self._request_queue[i];
|
||||||
|
this.self._request_queue.splice(i,1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.self._lastModification = _response.lastModification;
|
this.self._lastModification = _response.lastModification;
|
||||||
|
|
||||||
// Do nothing if _response.order evaluates to false
|
// Do nothing if _response.order evaluates to false
|
||||||
@@ -903,6 +989,9 @@ var et2_dataview_controller = (function(){ "use strict"; return Class.extend({
|
|||||||
|
|
||||||
// Schedule an invalidate, in case total is the same
|
// Schedule an invalidate, in case total is the same
|
||||||
this.self._grid.invalidate();
|
this.self._grid.invalidate();
|
||||||
|
|
||||||
|
// Check if requests are waiting
|
||||||
|
this.self._fetchQueuedRequest();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user