Skip to content

Commit

Permalink
Batch mget requests on dashboard load and cache field_stat results (#…
Browse files Browse the repository at this point in the history
…10273)

Backports PR #10081

**Commit 1:**
defer loading visualization saved objects so they can be loaded in a single _mget

* Original sha: 5c1344e
* Authored by nreese <[email protected]> on 2017-01-24T23:41:05Z

**Commit 2:**
Merge branch 'defer' of https://github.com/nreese/kibana into nreese-defer

* Original sha: 96af3ea
* Authored by Stacey Gammon <[email protected]> on 2017-01-26T13:44:55Z

**Commit 3:**
Don't request field stats more than once for the same index pattern

* Original sha: 9a02e5b
* Authored by Stacey Gammon <[email protected]> on 2017-01-26T15:57:34Z

**Commit 4:**
[ui/courier] batch fetch requests for all searches and docs

* Original sha: 20d55fe
* Authored by spalger <[email protected]> on 2017-02-06T22:13:23Z

**Commit 5:**
[ui/courier] remove remaining mentions of req.isFetchRequested()

* Original sha: f5bd5ca
* Authored by spalger <[email protected]> on 2017-02-08T21:22:32Z

**Commit 6:**
[courier/fetch/request] remove unneceessary !!

* Original sha: eb5446d
* Authored by spalger <[email protected]> on 2017-02-09T20:48:48Z
  • Loading branch information
elastic-jasper authored and epixa committed Feb 9, 2017
1 parent e661dd3 commit 26e3721
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 13 deletions.
29 changes: 19 additions & 10 deletions src/ui/public/courier/fetch/fetch.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,32 @@ import ReqStatusProvider from './req_status';
export default function fetchService(Private, Promise) {

const requestQueue = Private(RequestQueueProvider);
const fetchThese = Private(FetchTheseProvider);

const immediatelyFetchThese = Private(FetchTheseProvider);
const callResponseHandlers = Private(CallResponseHandlersProvider);
const INCOMPLETE = Private(ReqStatusProvider).INCOMPLETE;

function fetchQueued(strategy) {
const requests = requestQueue.getStartable(strategy);
if (!requests.length) return Promise.resolve();
else return fetchThese(requests);
}
const debouncedFetchThese = _.debounce(() => {
const requests = requestQueue.get().filter(req => req.isFetchRequestedAndPending());
immediatelyFetchThese(requests);
}, {
wait: 10,
maxWait: 50
});

this.fetchQueued = fetchQueued;
const fetchTheseSoon = (requests) => {
requests.forEach(req => req._setFetchRequested());
debouncedFetchThese();
return Promise.all(requests.map(req => req.defer.promise));
};

this.fetchQueued = (strategy) => {
return fetchTheseSoon(requestQueue.getStartable(strategy));
};

function fetchASource(source, strategy) {
const defer = Promise.defer();

fetchThese([
fetchTheseSoon([
source._createRequest(defer)
]);

Expand All @@ -50,7 +59,7 @@ export default function fetchService(Private, Promise) {
* @param {array} reqs - the requests to fetch
* @async
*/
this.these = fetchThese;
this.these = fetchTheseSoon;

/**
* Send responses to a list of requests, used when requests
Expand Down
34 changes: 32 additions & 2 deletions src/ui/public/courier/fetch/request/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,42 @@ export default function AbstractReqProvider(Private, Promise) {
this.source = source;
this.defer = defer || Promise.defer();
this._whenAbortedHandlers = [];

requestQueue.push(this);
}

/**
* Called by the loopers to find requests that should be sent to the
* fetch() module. When a module is sent to fetch() it's _fetchRequested flag
* is set, and this consults that flag so requests are not send to fetch()
* multiple times.
*
* @return {Boolean}
*/
canStart() {
return Boolean(!this.stopped && !this.source._fetchDisabled);
return !this._fetchRequested && !this.stopped && !this.source._fetchDisabled;
}

/**
* Used to find requests that were previously sent to the fetch() module but
* have not been started yet, so they can be started.
*
* @return {Boolean}
*/
isFetchRequestedAndPending() {
return this._fetchRequested && !this.started;
}

/**
* Called by the fetch() module when this request has been sent to
* be fetched. At that point the request is somewhere between `ready-to-start`
* and `started`. The fetch module then waits a short period of time to
* allow requests to build up in the request queue, and then immediately
* fetches all requests that return true from `isFetchRequestedAndPending()`
*
* @return {undefined}
*/
_setFetchRequested() {
this._fetchRequested = true;
}

start() {
Expand Down
8 changes: 7 additions & 1 deletion src/ui/public/courier/fetch/strategy/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ export default function FetchStrategyForSearch(Private, Promise, timefilter, kbn
* @return {Promise} - a promise that is fulfilled by the request body
*/
reqsFetchParamsToBody: function (reqsFetchParams) {
const indexToListMapping = {};

return Promise.map(reqsFetchParams, function (fetchParams) {
return Promise.resolve(fetchParams.index)
.then(function (indexList) {
Expand All @@ -23,7 +25,11 @@ export default function FetchStrategyForSearch(Private, Promise, timefilter, kbn
}

const timeBounds = timefilter.getBounds();
return indexList.toIndexList(timeBounds.min, timeBounds.max);

if (!indexToListMapping[indexList.id]) {
indexToListMapping[indexList.id] = indexList.toIndexList(timeBounds.min, timeBounds.max);
}
return indexToListMapping[indexList.id];
})
.then(function (indexList) {
let body = fetchParams.body || {};
Expand Down

0 comments on commit 26e3721

Please sign in to comment.