Skip to content

Commit

Permalink
add polling on UI
Browse files Browse the repository at this point in the history
  • Loading branch information
VladLasitsa committed Aug 12, 2020
1 parent e16dc13 commit 5d259b9
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 47 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import moment from 'moment';
import { coreMock } from '../../../../core/public/mocks';
import { dataPluginMock } from '../../../data/public/mocks';
import { getTimelionRequestHandler } from './timelion_request_handler';

describe('Timelion request handler', function () {
const core = coreMock.createStart();
const data = dataPluginMock.createStartContract();
let timelionRequestHandler: any;

beforeEach(function () {
core.http.post
.mockReturnValueOnce(Promise.resolve({ sheet: [{ is_running: true }] }))
.mockReturnValueOnce(Promise.resolve({ sheet: [{ is_running: false }] }));

data.query.timefilter.timefilter.calculateBounds = () => {
return { min: moment(), max: moment() };
};
timelionRequestHandler = getTimelionRequestHandler({
uiSettings: core.uiSettings,
http: core.http,
timefilter: data.query.timefilter.timefilter,
});
});

it('checking polling', async function () {
await timelionRequestHandler({
timeRange: {},
filters: [],
query: { query: 'es' },
visParams: { expression: 'es' },
});
expect(core.http.post).toHaveBeenCalledTimes(2);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -94,24 +94,48 @@ export function getTimelionRequestHandler({

// parse the time range client side to make sure it behaves like other charts
const timeRangeBounds = timefilter.calculateBounds(timeRange);
const filter = esQuery.buildEsQuery(undefined, query, filters, esQueryConfigs);

try {
return await http.post('/api/timelion/run', {
body: JSON.stringify({
sheet: [expression],
extended: {
es: {
filter: esQuery.buildEsQuery(undefined, query, filters, esQueryConfigs),
const MAX_INTERVAL = 120000;

async function runPolling(interval: number): Promise<TimelionSuccessResponse> {
async function checkCondition(resolve: Function, reject: Function) {
const resp = await http.post('/api/timelion/run', {
body: JSON.stringify({
sheet: [expression],
extended: {
es: {
filter,
},
},
time: {
from: timeRangeBounds.min,
to: timeRangeBounds.max,
interval: visParams.interval,
timezone,
},
},
time: {
from: timeRangeBounds.min,
to: timeRangeBounds.max,
interval: visParams.interval,
timezone,
},
}),
});
}),
});

if (interval > MAX_INTERVAL) {
reject('Reach max interval');
}

if (resp.sheet.some((sheet: any) => sheet.is_running || sheet.is_partial)) {
setTimeout(() => {
interval = interval * Math.log10(interval / 10);
checkCondition(resolve, reject);
}, interval);
} else {
resolve(resp);
}
}

return new Promise(checkCondition);
}

try {
return await runPolling(500);
} catch (e) {
if (e && e.body) {
const err = new Error(
Expand Down
40 changes: 9 additions & 31 deletions src/plugins/vis_type_timelion/server/series_functions/es/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,38 +129,14 @@ export default new Datasource('es', {

const body = buildRequest(config, tlConfig, scriptedFields, esShardTimeout);

const MAX_INTERVAL = 300000;
const resp = await tlConfig.esDataClient(
tlConfig.context,
{
params: body,
},
{}
);

async function searchWithPolling(search, requestParams, interval) {
async function checkCondition(resolve, reject) {
const resp = await search(
tlConfig.context,
{
params: requestParams,
},
{}
);

if (interval > MAX_INTERVAL) {
reject('Reach max interval');
}

if (resp.is_running || resp.is_partial) {
setTimeout(() => {
interval = interval * Math.log10(interval / 100);
checkCondition(resolve, reject);
}, interval);
} else {
console.log(resp);
resolve(resp);
}
}

return new Promise(checkCondition);
}

const resp = await searchWithPolling(tlConfig.esDataClient, body, 10000);
console.log(resp);
if (!resp.rawResponse._shards.total) {
throw new Error(
i18n.translate('timelion.serverSideErrors.esFunction.indexNotFoundErrorMessage', {
Expand All @@ -172,6 +148,8 @@ export default new Datasource('es', {
);
}
return {
is_running: resp.is_running,
is_partial: resp.is_partial,
type: 'seriesList',
list: toSeriesList(resp.rawResponse.aggregations, config),
};
Expand Down

0 comments on commit 5d259b9

Please sign in to comment.