Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Converting indexPattern to indexList is now async #5173

Merged
merged 2 commits into from
Oct 22, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/testUtils/stubIndexPattern.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ define(function (require) {
return function (Private) {
var _ = require('lodash');
var sinon = require('sinon');
var Promise = require('bluebird');
var IndexedArray = require('ui/IndexedArray');
var IndexPattern = require('ui/index_patterns/_index_pattern');
var fieldFormats = Private(require('ui/registry/field_formats'));
Expand All @@ -21,7 +22,7 @@ define(function (require) {
this.fieldFormatMap = {};
this.routes = IndexPattern.prototype.routes;

this.toIndexList = _.constant([pattern]);
this.toIndexList = _.constant(Promise.resolve([pattern]));
this.getComputedFields = _.bind(getComputedFields, this);
this.flattenHit = flattenHit(this);
this.formatHit = formatHit(this, fieldFormats.getDefaultInstance('string'));
Expand Down
40 changes: 27 additions & 13 deletions src/ui/public/courier/fetch/request/segmented.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ define(function (require) {
this._maxSegments = config.get('courier:maxSegmentCount');
this._hitsReceived = 0;
this._direction = 'desc';
this._queueCreated = false;
this._handle = new SegmentedHandle(this);

// prevent the source from changing between requests,
Expand All @@ -33,9 +34,13 @@ define(function (require) {
*********/

SegmentedReq.prototype.start = function () {
var self = this;

this._complete = [];
this._active = null;
this._segments = [];
this._all = [];
this._queue = [];

this._mergedResp = {
took: 0,
Expand All @@ -49,11 +54,12 @@ define(function (require) {
// give the request consumer a chance to receive each segment and set
// parameters via the handle
if (_.isFunction(this._initFn)) this._initFn(this._handle);
this._createQueue();
this._all = this._queue.slice(0);
this._createQueue().then(function (queue) {
self._all = queue.slice(0);

// Send the initial fetch status
this._reportStatus();
// Send the initial fetch status
self._reportStatus();
});

return SearchReq.prototype.start.call(this);
};
Expand Down Expand Up @@ -100,7 +106,9 @@ define(function (require) {
};

SegmentedReq.prototype.isIncomplete = function () {
return this._queue.length > 0;
var queueNotCreated = !this._queueCreated;
var queueNotEmpty = this._queue.length > 0;
return queueNotCreated || queueNotEmpty;
};

SegmentedReq.prototype.clone = function () {
Expand Down Expand Up @@ -157,22 +165,28 @@ define(function (require) {
};

SegmentedReq.prototype._createQueue = function () {
var self = this;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like we should be setting this._queueCreated = false; here, and this._queueCreated = true; below by self._queue = ...;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that we should flag the queue as created inside createQueue itself. Good catch.

I still think it makes sense to default _queueCreated to false during instantiation though since it can technically be leveraged (via reportStatus) prior to start() being invoked.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

var timeBounds = timefilter.getBounds();
var indexPattern = this.source.get('index');
var queue = indexPattern.toIndexList(timeBounds.min, timeBounds.max);

if (!_.isArray(queue)) queue = [queue];
if (this._direction === 'desc') queue = queue.reverse();
return indexPattern.toIndexList(timeBounds.min, timeBounds.max)
.then(function (queue) {
if (!_.isArray(queue)) queue = [queue];
if (self._direction === 'desc') queue = queue.reverse();

self._queue = queue;
self._queueCreated = true;

return (this._queue = queue);
return queue;
});
};

SegmentedReq.prototype._reportStatus = function () {
return this._handle.emit('status', {
total: this._all.length,
complete: this._complete.length,
remaining: this._queue.length,
hitCount: this._mergedResp.hits.hits.length
total: this._queueCreated ? this._all.length : NaN,
complete: this._queueCreated ? this._complete.length : NaN,
remaining: this._queueCreated ? this._queue.length : NaN,
hitCount: this._queueCreated ? this._mergedResp.hits.hits.length : NaN
});
};

Expand Down
6 changes: 3 additions & 3 deletions src/ui/public/courier/fetch/strategy/doc.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ define(function (require) {
/**
* Flatten a series of requests into as ES request body
* @param {array} requests - an array of flattened requests
* @return {string} - the request body
* @return {Promise} - a promise that is fulfilled by the request body
*/
reqsFetchParamsToBody: function (reqsFetchParams) {
return {
return Promise.resolve({
docs: reqsFetchParams
};
});
},

/**
Expand Down
37 changes: 22 additions & 15 deletions src/ui/public/courier/fetch/strategy/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,33 @@ define(function (require) {
* Flatten a series of requests into as ES request body
*
* @param {array} requests - the requests to serialize
* @return {string} - the request body
* @return {Promise} - a promise that is fulfilled by the request body
*/
reqsFetchParamsToBody: function (reqsFetchParams) {
return reqsFetchParams.map(function (fetchParams) {
var indexList = fetchParams.index;
return Promise.map(reqsFetchParams, function (fetchParams) {
return Promise.resolve(fetchParams.index)
.then(function (indexList) {
if (!_.isFunction(_.get(indexList, 'toIndexList'))) {
return indexList;
}

if (_.isFunction(_.get(indexList, 'toIndexList'))) {
var timeBounds = timefilter.getBounds();
indexList = indexList.toIndexList(timeBounds.min, timeBounds.max);
}

return angular.toJson({
index: indexList,
type: fetchParams.type,
search_type: fetchParams.search_type,
ignore_unavailable: true
return indexList.toIndexList(timeBounds.min, timeBounds.max);
})
+ '\n'
+ angular.toJson(fetchParams.body || {});
}).join('\n') + '\n';
.then(function (indexList) {
return angular.toJson({
index: indexList,
type: fetchParams.type,
search_type: fetchParams.search_type,
ignore_unavailable: true
})
+ '\n'
+ angular.toJson(fetchParams.body || {});
});
})
.then(function (requests) {
return requests.join('\n') + '\n';
});
},

/**
Expand Down
15 changes: 9 additions & 6 deletions src/ui/public/index_patterns/_index_pattern.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,12 +176,15 @@ define(function (require) {
};

self.toIndexList = function (start, stop) {
var interval = this.getInterval();
if (interval) {
return intervals.toIndexList(self.id, interval, start, stop);
} else {
return self.id;
}
var self = this;
return new Promise(function (resolve) {
var interval = self.getInterval();
if (interval) {
resolve(intervals.toIndexList(self.id, interval, start, stop));
} else {
resolve(self.id);
}
});
};

self.prepBody = function () {
Expand Down
37 changes: 17 additions & 20 deletions src/ui/public/validate_query/validate_query.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ define(function (require) {

require('ui/modules')
.get('kibana')
.directive('validateQuery', function (es, $compile, timefilter, kbnIndex, debounce, Private) {
.directive('validateQuery', function (es, $compile, timefilter, kbnIndex, debounce, Promise, Private) {
var fromUser = Private(require('ui/validate_query/lib/from_user'));
var toUser = require('ui/validate_query/lib/to_user');

Expand All @@ -32,40 +32,37 @@ define(function (require) {
};

function validator(query) {
var index;
var type;
if (request.abort) request.abort();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order for request.abort to exist it needs to be the exact promise that was returned by the es client. These changes set request on line 39 instead, so request.abort() will never be defined.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... I'm not sure if this ever worked then. The promise that was set on request wasn't the raw promise returned by the es client even before these changes.

This is what existed before:

screen shot 2015-10-22 at 1 05 39 pm

So request was actually set to a new promise that was returned by .then(success, error).

If that was indeed a bug already, this PR has a bit of urgency to it since it's needed for other PRs, so I'd rather address the bug in a subsequent PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed


if ($scope.queryInput) {
useSearchSource();
} else {
useDefaults();
}
var prepare = $scope.queryInput ? useSearchSource : useDefaults;

return sendRequest();
request = prepare().then(sendRequest);

function useSearchSource() {
var pattern = $scope.queryInput.get('index');
if (!pattern) return useDefaults();

if (_.isString(pattern)) {
index = pattern;
} else if (_.isFunction(pattern.toIndexList)) {
index = pattern.toIndexList();
return Promise.resolve({ index: pattern });
} else if (_.isFunction(_.get(pattern, 'toIndexList'))) {
return pattern.toIndexList().then(function (indexList) {
return { index: indexList };
});
} else {
useDefaults();
return useDefaults();
}
}

function useDefaults() {
index = kbnIndex;
type = '__kibanaQueryValidator';
return Promise.resolve({
index: kbnIndex,
type: '__kibanaQueryValidator'
});
}

function sendRequest() {
request = es.indices.validateQuery({
index: index,
type: type,
function sendRequest(config) {
return es.indices.validateQuery({
index: config.index,
type: config.type,
explain: true,
ignoreUnavailable: true,
body: {
Expand Down