Skip to content

Commit

Permalink
TSVB field list performance issue on using annotations (#84407) (#84484)
Browse files Browse the repository at this point in the history
* TSVB field list performance issue on using annotations

* Add AbortController to fetchFields and change translation id in annotations_editor

* Rename fetchFields to debouncedFetchFields

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
DianaDerevyankina and kibanamachine authored Nov 30, 2020
1 parent ffe6614 commit b54b97b
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 22 deletions.
1 change: 1 addition & 0 deletions src/plugins/vis_type_timeseries/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ export const INDEXES_SEPARATOR = ',';
export const AUTO_INTERVAL = 'auto';
export const ROUTES = {
VIS_DATA: '/api/metrics/vis/data',
FIELDS: '/api/metrics/fields',
};
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ function FieldSelectUi({
}

FieldSelectUi.defaultProps = {
indexPattern: '*',
indexPattern: '',
disabled: false,
restrict: [],
placeholder: i18n.translate('visTypeTimeseries.fieldSelect.selectFieldPlaceholder', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,14 @@ import {
EuiCode,
EuiText,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';

function newAnnotation() {
return {
id: uuid.v1(),
color: '#F00',
index_pattern: '*',
index_pattern: '',
time_field: '@timestamp',
icon: 'fa-tag',
ignore_global_filters: 1,
Expand Down Expand Up @@ -84,7 +85,7 @@ export class AnnotationsEditor extends Component {
const defaults = {
fields: '',
template: '',
index_pattern: '*',
index_pattern: '',
query_string: { query: '', language: getDefaultQueryLanguage() },
};
const model = { ...defaults, ...row };
Expand All @@ -100,6 +101,8 @@ export class AnnotationsEditor extends Component {
const htmlId = htmlIdGenerator(model.id);
const handleAdd = collectionActions.handleAdd.bind(null, this.props, newAnnotation);
const handleDelete = collectionActions.handleDelete.bind(null, this.props, model);
const defaultIndexPattern = this.props.model.default_index_pattern;

return (
<div className="tvbAnnotationsEditor" key={model.id}>
<EuiFlexGroup responsive={false}>
Expand All @@ -120,14 +123,22 @@ export class AnnotationsEditor extends Component {
label={
<FormattedMessage
id="visTypeTimeseries.annotationsEditor.indexPatternLabel"
defaultMessage="Index pattern (required)"
defaultMessage="Index pattern"
/>
}
helpText={
defaultIndexPattern &&
!model.index_pattern &&
i18n.translate('visTypeTimeseries.annotationsEditor.searchByDefaultIndex', {
defaultMessage: 'Default index pattern is used. To query all indexes use *',
})
}
fullWidth
>
<EuiFieldText
onChange={this.handleChange(model, 'index_pattern')}
value={model.index_pattern}
placeholder={defaultIndexPattern}
fullWidth
/>
</EuiFormRow>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,19 @@ export class VisEditor extends Component {
});
}, VIS_STATE_DEBOUNCE_DELAY);

debouncedFetchFields = debounce(
(extractedIndexPatterns) => {
if (this.abortControllerFetchFields) {
this.abortControllerFetchFields.abort();
}
this.abortControllerFetchFields = new AbortController();

return fetchFields(extractedIndexPatterns, this.abortControllerFetchFields.signal);
},
VIS_STATE_DEBOUNCE_DELAY,
{ leading: true }
);

handleChange = (partialModel) => {
if (isEmpty(partialModel)) {
return;
Expand All @@ -94,7 +107,7 @@ export class VisEditor extends Component {

const extractedIndexPatterns = extractIndexPatterns(nextModel);
if (!isEqual(this.state.extractedIndexPatterns, extractedIndexPatterns)) {
fetchFields(extractedIndexPatterns).then((visFields) =>
this.debouncedFetchFields(extractedIndexPatterns).then((visFields) =>
this.setState({
visFields,
extractedIndexPatterns,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,34 +19,40 @@
import { i18n } from '@kbn/i18n';
import { extractIndexPatterns } from '../../../common/extract_index_patterns';
import { getCoreStart } from '../../services';
import { ROUTES } from '../../../common/constants';

export async function fetchFields(indexPatterns = ['*']) {
export async function fetchFields(indexPatterns = [], signal) {
const patterns = Array.isArray(indexPatterns) ? indexPatterns : [indexPatterns];
try {
const indexFields = await Promise.all(
patterns.map((pattern) => {
return getCoreStart().http.get('/api/metrics/fields', {
patterns.map((pattern) =>
getCoreStart().http.get(ROUTES.FIELDS, {
query: {
index: pattern,
},
});
})
signal,
})
)
);
const fields = patterns.reduce((cumulatedFields, currentPattern, index) => {
return {

return patterns.reduce(
(cumulatedFields, currentPattern, index) => ({
...cumulatedFields,
[currentPattern]: indexFields[index],
};
}, {});
return fields;
} catch (error) {
getCoreStart().notifications.toasts.addDanger({
title: i18n.translate('visTypeTimeseries.fetchFields.loadIndexPatternFieldsErrorMessage', {
defaultMessage: 'Unable to load index_pattern fields',
}),
text: error.message,
});
{}
);
} catch (error) {
if (error.name !== 'AbortError') {
getCoreStart().notifications.toasts.addDanger({
title: i18n.translate('visTypeTimeseries.fetchFields.loadIndexPatternFieldsErrorMessage', {
defaultMessage: 'Unable to load index_pattern fields',
}),
text: error.message,
});
}
}
return [];
}

export async function fetchIndexPatternFields({ params, fields = {} }) {
Expand Down
3 changes: 2 additions & 1 deletion src/plugins/vis_type_timeseries/server/routes/fields.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@ import { isBoom } from '@hapi/boom';
import { schema } from '@kbn/config-schema';
import { getFields } from '../lib/get_fields';
import { Framework } from '../plugin';
import { ROUTES } from '../../common/constants';

export const fieldsRoutes = (framework: Framework) => {
framework.router.get(
{
path: '/api/metrics/fields',
path: ROUTES.FIELDS,
validate: {
query: schema.object({ index: schema.string() }),
},
Expand Down

0 comments on commit b54b97b

Please sign in to comment.