mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[courier] resolve looper iteration when requests are aborted
The search looper returns the promise from search executions to ensure that subsequent loops do not run until the previous loop has completed. This causes the looper to get stuck when all of the aborted requests are completed, as completed requests do not resolve or reject their promises, causing the looper to never allow another search loop. Since this behavior is desirable for pages where we don't want to execute the `.then()` or `.catch()` callbacks for requests that were aborted, we work around it in this specific case by creating a promise that is resolved when each request is either aborted or completed.
This commit is contained in:
parent
9b39a19856
commit
1683e03b53
5 changed files with 22 additions and 9 deletions
|
@ -185,7 +185,7 @@ export default function SourceAbstractFactory(Private, Promise, PromiseEmitter)
|
|||
|
||||
courierFetch.these([req]);
|
||||
|
||||
return req.defer.promise;
|
||||
return req.getCompletePromise();
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -175,7 +175,7 @@ export default function SearchSourceFactory(Promise, Private, config) {
|
|||
|
||||
// return promises created by the completion handler so that
|
||||
// errors will bubble properly
|
||||
return req.defer.promise.then(addRequest);
|
||||
return req.getCompletePromise().then(addRequest);
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ export default function fetchService(Private, Promise) {
|
|||
const fetchTheseSoon = (requests) => {
|
||||
requests.forEach(req => req._setFetchRequested());
|
||||
debouncedFetchThese();
|
||||
return Promise.all(requests.map(req => req.defer.promise));
|
||||
return Promise.all(requests.map(req => req.getCompletePromise()));
|
||||
};
|
||||
|
||||
this.fetchQueued = (strategy) => {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import _ from 'lodash';
|
||||
import moment from 'moment';
|
||||
import { race } from 'bluebird';
|
||||
|
||||
import errors from 'ui/errors';
|
||||
|
||||
|
@ -14,7 +15,7 @@ export default function AbstractReqProvider(Private, Promise) {
|
|||
constructor(source, defer) {
|
||||
this.source = source;
|
||||
this.defer = defer || Promise.defer();
|
||||
this._whenAbortedHandlers = [];
|
||||
this.abortedDefer = Promise.defer();
|
||||
requestQueue.push(this);
|
||||
}
|
||||
|
||||
|
@ -120,11 +121,12 @@ export default function AbstractReqProvider(Private, Promise) {
|
|||
this._markStopped();
|
||||
this.defer = null;
|
||||
this.aborted = true;
|
||||
_.callEach(this._whenAbortedHandlers);
|
||||
this.abortedDefer.resolve();
|
||||
this.abortedDefer = null;
|
||||
}
|
||||
|
||||
whenAborted(cb) {
|
||||
this._whenAbortedHandlers.push(cb);
|
||||
this.abortedDefer.promise.then(cb);
|
||||
}
|
||||
|
||||
complete() {
|
||||
|
@ -133,6 +135,14 @@ export default function AbstractReqProvider(Private, Promise) {
|
|||
this.defer.resolve(this.resp);
|
||||
}
|
||||
|
||||
getCompletePromise() {
|
||||
return this.defer.promise;
|
||||
}
|
||||
|
||||
getCompleteOrAbortedPromise() {
|
||||
return race([ this.defer.promise, this.abortedDefer.promise ]);
|
||||
}
|
||||
|
||||
clone() {
|
||||
return new this.constructor(this.source, this.defer);
|
||||
}
|
||||
|
|
|
@ -17,9 +17,12 @@ export default function SearchLooperService(Private, Promise, Notifier, $rootSco
|
|||
*/
|
||||
const searchLooper = new Looper(null, function () {
|
||||
$rootScope.$broadcast('courier:searchRefresh');
|
||||
return fetch.these(
|
||||
requestQueue.getInactive(searchStrategy)
|
||||
);
|
||||
const requests = requestQueue.getInactive(searchStrategy);
|
||||
// promise returned from fetch.these() only resolves when
|
||||
// the requests complete, but we want to continue even if
|
||||
// the requests abort so we make our own
|
||||
fetch.these(requests);
|
||||
return Promise.all(requests.map(r => r.getCompleteOrAbortedPromise()));
|
||||
});
|
||||
|
||||
searchLooper.onHastyLoop = function () {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue