Skip to content
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
45 changes: 37 additions & 8 deletions x-pack/legacy/plugins/maps/public/actions/map_actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ import {
getTooltipState
} from '../selectors/map_selectors';
import { FLYOUT_STATE } from '../reducers/ui';
import {
cancelRequest,
registerCancelCallback,
unregisterCancelCallback
} from '../reducers/non_serializable_instances';
import { updateFlyout } from '../actions/ui_actions';
import { SOURCE_DATA_ID_ORIGIN } from '../../common/constants';

Expand Down Expand Up @@ -64,7 +69,8 @@ function getLayerLoadingCallbacks(dispatch, layerId) {
onLoadError: (dataId, requestToken, errorMessage) => dispatch(onDataLoadError(layerId, dataId, requestToken, errorMessage)),
updateSourceData: (newData) => {
dispatch(updateSourceDataRequest(layerId, newData));
}
},
registerCancelCallback: (requestToken, callback) => dispatch(registerCancelCallback(requestToken, callback)),
};
}

Expand All @@ -84,6 +90,16 @@ async function syncDataForAllLayers(getState, dispatch, dataFilters) {
await Promise.all(syncs);
}

export function cancelAllInFlightRequests() {
return (dispatch, getState) => {
getLayerList(getState()).forEach(layer => {
layer.getInFlightRequestTokens().forEach(requestToken => {
dispatch(cancelRequest(requestToken));
});
});
};
}

export function setMapInitError(errorMessage) {
return {
type: SET_MAP_INIT_ERROR,
Expand Down Expand Up @@ -408,13 +424,20 @@ export function clearGoto() {
}

export function startDataLoad(layerId, dataId, requestToken, meta = {}) {
return ({
meta,
type: LAYER_DATA_LOAD_STARTED,
layerId,
dataId,
requestToken
});
return (dispatch, getState) => {
const layer = getLayerById(layerId, getState());
if (layer) {
dispatch(cancelRequest(layer.getPrevRequestToken(dataId)));
}

dispatch({
meta,
type: LAYER_DATA_LOAD_STARTED,
layerId,
dataId,
requestToken
});
};
}

export function updateSourceDataRequest(layerId, newData) {
Expand All @@ -432,6 +455,7 @@ export function updateSourceDataRequest(layerId, newData) {

export function endDataLoad(layerId, dataId, requestToken, data, meta) {
return async (dispatch) => {
dispatch(unregisterCancelCallback(requestToken));
dispatch(clearTooltipStateForLayer(layerId));
dispatch({
type: LAYER_DATA_LOAD_ENDED,
Expand All @@ -453,6 +477,7 @@ export function endDataLoad(layerId, dataId, requestToken, data, meta) {

export function onDataLoadError(layerId, dataId, requestToken, errorMessage) {
return async (dispatch) => {
dispatch(unregisterCancelCallback(requestToken));
dispatch(clearTooltipStateForLayer(layerId));
dispatch({
type: LAYER_DATA_LOAD_ERROR,
Expand Down Expand Up @@ -570,6 +595,10 @@ export function removeLayer(layerId) {
if (!layerGettingRemoved) {
return;
}

layerGettingRemoved.getInFlightRequestTokens().forEach(requestToken => {
dispatch(cancelRequest(requestToken));
});
dispatch(clearTooltipStateForLayer(layerId));
layerGettingRemoved.destroy();
dispatch({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { GisMap } from './view';
import { FLYOUT_STATE } from '../../reducers/ui';
import { exitFullScreen } from '../../actions/ui_actions';
import { getFlyoutDisplay, getIsFullScreen } from '../../selectors/ui_selectors';
import { triggerRefreshTimer } from '../../actions/map_actions';
import { triggerRefreshTimer, cancelAllInFlightRequests } from '../../actions/map_actions';
import {
areLayersLoaded,
getRefreshConfig,
Expand All @@ -35,6 +35,7 @@ function mapDispatchToProps(dispatch) {
return {
triggerRefreshTimer: () => dispatch(triggerRefreshTimer()),
exitFullScreen: () => dispatch(exitFullScreen()),
cancelAllInFlightRequests: () => dispatch(cancelAllInFlightRequests()),
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export class GisMap extends Component {
componentWillUnmount() {
this._isMounted = false;
this._clearRefreshTimer();
this.props.cancelAllInFlightRequests();
}

// Reporting uses both a `data-render-complete` attribute and a DOM event listener to determine
Expand Down
20 changes: 19 additions & 1 deletion x-pack/legacy/plugins/maps/public/layers/layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export class AbstractLayer {
}

destroy() {
if(this._source) {
if (this._source) {
this._source.destroy();
}
}
Expand Down Expand Up @@ -251,6 +251,24 @@ export class AbstractLayer {
return this._source.renderSourceSettingsEditor({ onChange });
};

getPrevRequestToken(dataId) {
const prevDataRequest = this.getDataRequest(dataId);
if (!prevDataRequest) {
return;
}

return prevDataRequest.getRequestToken();
}

getInFlightRequestTokens() {
if (!this._dataRequests) {
return [];
}

const requestTokens = this._dataRequests.map(dataRequest => dataRequest.getRequestToken());
return _.compact(requestTokens);
}

getSourceDataRequest() {
return this.getDataRequest(SOURCE_DATA_ID_ORIGIN);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,14 +183,18 @@ export class ESGeoGridSource extends AbstractESSource {
});
}

async getGeoJsonWithMeta(layerName, searchFilters) {
async getGeoJsonWithMeta(layerName, searchFilters, registerCancelCallback) {
const indexPattern = await this._getIndexPattern();
const searchSource = await this._makeSearchSource(searchFilters, 0);
const aggConfigs = new AggConfigs(indexPattern, this._makeAggConfigs(searchFilters.geogridPrecision), aggSchemas.all);
searchSource.setField('aggs', aggConfigs.toDsl());
const esResponse = await this._runEsQuery(layerName, searchSource, i18n.translate('xpack.maps.source.esGrid.inspectorDescription', {
defaultMessage: 'Elasticsearch geo grid aggregation request'
}));
const esResponse = await this._runEsQuery(
layerName,
searchSource,
registerCancelCallback,
i18n.translate('xpack.maps.source.esGrid.inspectorDescription', {
defaultMessage: 'Elasticsearch geo grid aggregation request'
}));

const tabifiedResp = tabifyAggResponse(aggConfigs, esResponse);
const { featureCollection } = convertToGeoJson({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ export class ESPewPewSource extends AbstractESSource {
return Math.min(targetGeotileLevel, MAX_GEOTILE_LEVEL);
}

async getGeoJsonWithMeta(layerName, searchFilters) {
async getGeoJsonWithMeta(layerName, searchFilters, registerCancelCallback) {
const indexPattern = await this._getIndexPattern();
const metricAggConfigs = this.getMetricFields().map(metric => {
const metricAggConfig = {
Expand Down Expand Up @@ -233,9 +233,13 @@ export class ESPewPewSource extends AbstractESSource {
}
});

const esResponse = await this._runEsQuery(layerName, searchSource, i18n.translate('xpack.maps.source.pewPew.inspectorDescription', {
defaultMessage: 'Source-destination connections request'
}));
const esResponse = await this._runEsQuery(
layerName,
searchSource,
registerCancelCallback,
i18n.translate('xpack.maps.source.pewPew.inspectorDescription', {
defaultMessage: 'Source-destination connections request'
}));

const { featureCollection } = convertToLines(esResponse);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ export class ESSearchSource extends AbstractESSource {
];
}

async _getTopHits(layerName, searchFilters) {
async _getTopHits(layerName, searchFilters, registerCancelCallback) {
const {
topHitsSplitField,
topHitsTimeField,
Expand Down Expand Up @@ -185,7 +185,7 @@ export class ESSearchSource extends AbstractESSource {
}
});

const resp = await this._runEsQuery(layerName, searchSource, 'Elasticsearch document top hits request');
const resp = await this._runEsQuery(layerName, searchSource, registerCancelCallback, 'Elasticsearch document top hits request');

let hasTrimmedResults = false;
const allHits = [];
Expand All @@ -209,7 +209,7 @@ export class ESSearchSource extends AbstractESSource {
};
}

async _getSearchHits(layerName, searchFilters) {
async _getSearchHits(layerName, searchFilters, registerCancelCallback) {
const searchSource = await this._makeSearchSource(searchFilters, ES_SIZE_LIMIT);
// Setting "fields" instead of "source: { includes: []}"
// because SearchSource automatically adds the following by default
Expand All @@ -218,7 +218,7 @@ export class ESSearchSource extends AbstractESSource {
// By setting "fields", SearchSource removes all of defaults
searchSource.setField('fields', searchFilters.fieldNames);

const resp = await this._runEsQuery(layerName, searchSource, 'Elasticsearch document request');
const resp = await this._runEsQuery(layerName, searchSource, registerCancelCallback, 'Elasticsearch document request');

return {
hits: resp.hits.hits,
Expand All @@ -233,10 +233,10 @@ export class ESSearchSource extends AbstractESSource {
return !!(useTopHits && topHitsSplitField && topHitsTimeField);
}

async getGeoJsonWithMeta(layerName, searchFilters) {
async getGeoJsonWithMeta(layerName, searchFilters, registerCancelCallback) {
const { hits, meta } = this._isTopHits()
? await this._getTopHits(layerName, searchFilters)
: await this._getSearchHits(layerName, searchFilters);
? await this._getTopHits(layerName, searchFilters, registerCancelCallback)
: await this._getSearchHits(layerName, searchFilters, registerCancelCallback);

const indexPattern = await this._getIndexPattern();
const unusedMetaFields = indexPattern.metaFields.filter(metaField => {
Expand Down
12 changes: 11 additions & 1 deletion x-pack/legacy/plugins/maps/public/layers/sources/es_source.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { ESAggMetricTooltipProperty } from '../tooltips/es_aggmetric_tooltip_pro
import uuid from 'uuid/v4';
import { copyPersistentState } from '../../reducers/util';
import { ES_GEO_FIELD_TYPE } from '../../../common/constants';
import { DataRequestAbortError } from '../util/data_request';

export class AbstractESSource extends AbstractVectorSource {

Expand Down Expand Up @@ -131,7 +132,12 @@ export class AbstractESSource extends AbstractVectorSource {
}


async _runEsQuery(requestName, searchSource, requestDescription) {
async _runEsQuery(requestName, searchSource, registerCancelCallback, requestDescription) {
const cancel = () => {
searchSource.cancelQueued();
};
registerCancelCallback(cancel);

try {
return await fetchSearchSourceAndRecordWithInspector({
inspectorAdapters: this._inspectorAdapters,
Expand All @@ -141,6 +147,10 @@ export class AbstractESSource extends AbstractVectorSource {
requestDesc: requestDescription
});
} catch(error) {
if (error.name === 'AbortError') {
throw new DataRequestAbortError();
}

throw new Error(i18n.translate('xpack.maps.source.esSource.requestFailedErrorMessage', {
defaultMessage: `Elasticsearch search request failed, error: {message}`,
values: { message: error.message }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export class ESTermSource extends AbstractESSource {
return `${metricLabel} of ${this._descriptor.indexPatternTitle}:${this._descriptor.term}`;
}

async getPropertiesMap(searchFilters, leftSourceName, leftFieldName) {
async getPropertiesMap(searchFilters, leftSourceName, leftFieldName, registerCancelCallback) {

if (!this.hasCompleteConfig()) {
return [];
Expand All @@ -104,7 +104,7 @@ export class ESTermSource extends AbstractESSource {

const requestName = `${this._descriptor.indexPatternTitle}.${this._descriptor.term}`;
const requestDesc = this._getRequestDescription(leftSourceName, leftFieldName);
const rawEsData = await this._runEsQuery(requestName, searchSource, requestDesc);
const rawEsData = await this._runEsQuery(requestName, searchSource, registerCancelCallback, requestDesc);

const metricPropertyNames = configStates
.filter(configState => {
Expand Down
10 changes: 10 additions & 0 deletions x-pack/legacy/plugins/maps/public/layers/util/data_request.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,15 @@ export class DataRequest {
return this._descriptor.dataId;
}

getRequestToken() {
return this._descriptor.dataRequestToken;
}

}

export class DataRequestAbortError extends Error {
constructor() {
super();
}
}

Loading