Files
phabricator/webroot/rsrc/js/core/ShapedRequest.js

104 lines
2.4 KiB
JavaScript
Raw Normal View History

/**
* @requires javelin-install
* javelin-util
* javelin-request
Provide a global router for Ajax requests Summary: Fixes T430. Fixes T4834. Obsoletes D7641. Currently, we do some things less-well than we could: - We just let the browser queue and prioritize requests, so if you load a revision with 50 changes and then click "Award Token", the action blocks until the changes load in most/all browsers. It would be better to prioritize this action and queue it immediately. - Similarly, changes tend to load in order, even if the user has clicked to a specific file. When the user expresses a preference for a specific file, we should prioritize it. - We show a spinning GIF when waiting on requests. This is appropriate for some types of reuqests, but distracting for others. To fix this: - Queue all (or, at least, most) requests into a new queue in JX.Router. - JX.Router handles prioritizing the requests. Principally: - You can submit a request with a specific priority (500 = general content loading, 1000 = default, 2000 = explicit user action) and JX.Router will get the higher stuff fired off sooner. - You can name requests and then adjust their prorities later, if the user expresses an interest in specific results. - Only use the spinner gif for "workflow" requests, which is bascially when the user clicked something and we're waiting on the server. I think it's useful and not-annoying in this case. - Don't show any status for draft requests. - For content requests, show a subtle hipster-style top loading bar. Test Plan: - Viewed a diff with 93 changes, and clicked award token. - Prior to this patch, the action took many many seconds to resolve. - After this patch, it resolves quickly. - Viewed a diff with 93 changes and saw a pleasant subtle hipster-style loading bar. - Viewed a diff with 93 changes and typed some draft text. Previews populated fairly quickly and there was no spinner. - Viewed a diff with 93 changes and clicked something with workflow, saw a spinner after a moment. - Viewed a diff with 93 changes and clicked a file in the table of contents near the end of the list. - Prior to this patch, it took a long time to show up. - After this patch, it loads directly. Reviewers: chad, btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T430, T4834 Differential Revision: https://secure.phabricator.com/D8979
2014-05-05 10:57:42 -07:00
* javelin-router
* @provides phabricator-shaped-request
* @javelin
*/
/**
* Send requests with rate limiting and retries, in response to some application
* trigger. This is used to implement comment previews in Differential and
* Maniphest.
*/
JX.install('PhabricatorShapedRequest', {
construct : function(uri, callback, data_callback) {
this._uri = uri;
this._callback = callback;
this._dataCallback = data_callback;
},
events : ['error'],
members : {
_callback : null,
_dataCallback : null,
_request : null,
_min : null,
_defer : null,
_last : null,
start : function() {
this.trigger();
},
trigger : function() {
clearTimeout(this._defer);
var data = this._dataCallback();
// Waiting on a request, rate-limit.
var waiting = (this._request);
// Just got a request back, rate-limit.
var recent = (this._min && (new Date().getTime() < this._min));
if (!waiting && !recent && this.shouldSendRequest(this._last, data)) {
this._last = data;
this._request = new JX.Request(this._uri, JX.bind(this, function(r) {
this._callback(r);
this._min = new Date().getTime() + this.getRateLimit();
clearTimeout(this._defer);
this._defer = setTimeout(
JX.bind(this, this.trigger),
this.getRateLimit()
);
}));
this._request.listen('error', JX.bind(this, function(error) {
this.invoke('error', error, this);
}));
this._request.listen('finally', JX.bind(this, function() {
this._request = null;
}));
this._request.setData(data);
this._request.setTimeout(this.getRequestTimeout());
Provide a global router for Ajax requests Summary: Fixes T430. Fixes T4834. Obsoletes D7641. Currently, we do some things less-well than we could: - We just let the browser queue and prioritize requests, so if you load a revision with 50 changes and then click "Award Token", the action blocks until the changes load in most/all browsers. It would be better to prioritize this action and queue it immediately. - Similarly, changes tend to load in order, even if the user has clicked to a specific file. When the user expresses a preference for a specific file, we should prioritize it. - We show a spinning GIF when waiting on requests. This is appropriate for some types of reuqests, but distracting for others. To fix this: - Queue all (or, at least, most) requests into a new queue in JX.Router. - JX.Router handles prioritizing the requests. Principally: - You can submit a request with a specific priority (500 = general content loading, 1000 = default, 2000 = explicit user action) and JX.Router will get the higher stuff fired off sooner. - You can name requests and then adjust their prorities later, if the user expresses an interest in specific results. - Only use the spinner gif for "workflow" requests, which is bascially when the user clicked something and we're waiting on the server. I think it's useful and not-annoying in this case. - Don't show any status for draft requests. - For content requests, show a subtle hipster-style top loading bar. Test Plan: - Viewed a diff with 93 changes, and clicked award token. - Prior to this patch, the action took many many seconds to resolve. - After this patch, it resolves quickly. - Viewed a diff with 93 changes and saw a pleasant subtle hipster-style loading bar. - Viewed a diff with 93 changes and typed some draft text. Previews populated fairly quickly and there was no spinner. - Viewed a diff with 93 changes and clicked something with workflow, saw a spinner after a moment. - Viewed a diff with 93 changes and clicked a file in the table of contents near the end of the list. - Prior to this patch, it took a long time to show up. - After this patch, it loads directly. Reviewers: chad, btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T430, T4834 Differential Revision: https://secure.phabricator.com/D8979
2014-05-05 10:57:42 -07:00
var routable = this._request.getRoutable();
routable
.setType('draft')
.setPriority(750);
JX.Router.getInstance().queue(routable);
} else {
this._defer = setTimeout(
JX.bind(this, this.trigger),
this.getFrequency()
);
}
},
shouldSendRequest : function(last, data) {
if (last === null) {
return true;
}
for (var k in last) {
if (data[k] !== last[k]) {
return true;
}
}
return false;
}
},
properties : {
rateLimit : 500,
frequency : 1000,
requestTimeout : 20000
}
});