mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Add support for canceling in-flight requests
Repeat requests, if they already exist in the in-flight request map, will cause the previous request to cancel. The implementation of the unique key is the responsibility of individual datasources.
This commit is contained in:
parent
ffac5c1299
commit
6da7ed9706
@ -7,7 +7,7 @@ define([
|
|||||||
function (angular, _, coreModule, config) {
|
function (angular, _, coreModule, config) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
coreModule.default.service('backendSrv', function($http, alertSrv, $timeout) {
|
coreModule.default.service('backendSrv', function($http, alertSrv, $timeout, $q) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
this.get = function(url, params) {
|
this.get = function(url, params) {
|
||||||
@ -91,8 +91,25 @@ function (angular, _, coreModule, config) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var datasourceInFlightRequests = {};
|
||||||
|
var HTTP_REQUEST_ABORTED = -1;
|
||||||
this.datasourceRequest = function(options) {
|
this.datasourceRequest = function(options) {
|
||||||
options.retry = options.retry || 0;
|
options.retry = options.retry || 0;
|
||||||
|
|
||||||
|
// A cacheKey is provided by the datasource as a unique identifier for a
|
||||||
|
// particular query. If the cacheKey exists, the promise it is keyed to
|
||||||
|
// is canceled, canceling the previous datasource request if it is still
|
||||||
|
// in-flight.
|
||||||
|
var canceler;
|
||||||
|
if (options.cacheKey) {
|
||||||
|
if (canceler = datasourceInFlightRequests[options.cacheKey]) {
|
||||||
|
canceler.resolve();
|
||||||
|
}
|
||||||
|
canceler = $q.defer();
|
||||||
|
options.timeout = canceler.promise;
|
||||||
|
datasourceInFlightRequests[options.cacheKey] = canceler;
|
||||||
|
}
|
||||||
|
|
||||||
var requestIsLocal = options.url.indexOf('/') === 0;
|
var requestIsLocal = options.url.indexOf('/') === 0;
|
||||||
var firstAttempt = options.retry === 0;
|
var firstAttempt = options.retry === 0;
|
||||||
|
|
||||||
@ -102,10 +119,25 @@ function (angular, _, coreModule, config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return $http(options).then(null, function(err) {
|
return $http(options).then(null, function(err) {
|
||||||
|
if (err.status === HTTP_REQUEST_ABORTED) {
|
||||||
|
// Need to return the right data structure so it has no effect on
|
||||||
|
// iterating over returned data in datasource.ts#115
|
||||||
|
// TODO: Hitting another refresh cancels the "loading" animation on
|
||||||
|
// panes. Figure out how to keep it going.
|
||||||
|
return {
|
||||||
|
data: {
|
||||||
|
data: {
|
||||||
|
result: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// handle unauthorized for backend requests
|
// handle unauthorized for backend requests
|
||||||
if (requestIsLocal && firstAttempt && err.status === 401) {
|
if (requestIsLocal && firstAttempt && err.status === 401) {
|
||||||
return self.loginPing().then(function() {
|
return self.loginPing().then(function() {
|
||||||
options.retry = 1;
|
options.retry = 1;
|
||||||
|
canceler.resolve();
|
||||||
return self.datasourceRequest(options);
|
return self.datasourceRequest(options);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user