diff --git a/x-pack/plugins/maps/server/mvt/get_tile.ts b/x-pack/plugins/maps/server/mvt/get_tile.ts index 50c2014275a0..3274261cdba5 100644 --- a/x-pack/plugins/maps/server/mvt/get_tile.ts +++ b/x-pack/plugins/maps/server/mvt/get_tile.ts @@ -28,6 +28,10 @@ import { flattenHit } from './util'; import { ESBounds, tileToESBbox } from '../../common/geo_tile_utils'; import { getCentroidFeatures } from '../../common/get_centroid_features'; +function isAbortError(error: Error) { + return error.message === 'Request aborted' || error.message === 'Aborted'; +} + export async function getGridTile({ logger, context, @@ -40,6 +44,7 @@ export async function getGridTile({ requestType = RENDER_AS.POINT, geoFieldType = ES_GEO_FIELD_TYPE.GEO_POINT, searchSessionId, + abortSignal, }: { x: number; y: number; @@ -52,6 +57,7 @@ export async function getGridTile({ requestType: RENDER_AS; geoFieldType: ES_GEO_FIELD_TYPE; searchSessionId?: string; + abortSignal: AbortSignal; }): Promise { try { const tileBounds: ESBounds = tileToESBbox(x, y, z); @@ -72,6 +78,7 @@ export async function getGridTile({ }, { sessionId: searchSessionId, + abortSignal, } ) .toPromise(); @@ -83,7 +90,9 @@ export async function getGridTile({ return createMvtTile(featureCollection, z, x, y); } catch (e) { - logger.warn(`Cannot generate grid-tile for ${z}/${x}/${y}: ${e.message}`); + if (!isAbortError(e)) { + logger.warn(`Cannot generate grid-tile for ${z}/${x}/${y}: ${e.message}`); + } return null; } } @@ -99,6 +108,7 @@ export async function getTile({ requestBody = {}, geoFieldType, searchSessionId, + abortSignal, }: { x: number; y: number; @@ -110,6 +120,7 @@ export async function getTile({ requestBody: any; geoFieldType: ES_GEO_FIELD_TYPE; searchSessionId?: string; + abortSignal: AbortSignal; }): Promise { let features: Feature[]; try { @@ -119,6 +130,7 @@ export async function getTile({ const searchOptions = { sessionId: searchSessionId, + abortSignal, }; const countResponse = await context @@ -214,7 +226,9 @@ export async function getTile({ return createMvtTile(featureCollection, z, x, y); } catch (e) { - logger.warn(`Cannot generate tile for ${z}/${x}/${y}: ${e.message}`); + if (!isAbortError(e)) { + logger.warn(`Cannot generate tile for ${z}/${x}/${y}: ${e.message}`); + } return null; } } diff --git a/x-pack/plugins/maps/server/mvt/mvt_routes.ts b/x-pack/plugins/maps/server/mvt/mvt_routes.ts index 3e1617657958..1423e4ef5a20 100644 --- a/x-pack/plugins/maps/server/mvt/mvt_routes.ts +++ b/x-pack/plugins/maps/server/mvt/mvt_routes.ts @@ -10,6 +10,8 @@ import { schema } from '@kbn/config-schema'; import { KibanaRequest, KibanaResponseFactory, Logger } from 'src/core/server'; import { IRouter } from 'src/core/server'; import type { DataRequestHandlerContext } from 'src/plugins/data/server'; +// @ts-ignore not typed +import { AbortController } from 'abortcontroller-polyfill/dist/cjs-ponyfill'; import { MVT_GETTILE_API_PATH, API_ROOT_PATH, @@ -50,6 +52,12 @@ export function initMVTRoutes({ response: KibanaResponseFactory ) => { const { query } = request; + + const abortController = new AbortController(); + request.events.aborted$.subscribe(() => { + abortController.abort(); + }); + const requestBodyDSL = rison.decode(query.requestBody as string); const tile = await getTile({ @@ -63,6 +71,7 @@ export function initMVTRoutes({ requestBody: requestBodyDSL as any, geoFieldType: query.geoFieldType as ES_GEO_FIELD_TYPE, searchSessionId: query.searchSessionId, + abortSignal: abortController.signal, }); return sendResponse(response, tile); @@ -92,6 +101,11 @@ export function initMVTRoutes({ response: KibanaResponseFactory ) => { const { query } = request; + const abortController = new AbortController(); + request.events.aborted$.subscribe(() => { + abortController.abort(); + }); + const requestBodyDSL = rison.decode(query.requestBody as string); const tile = await getGridTile({ @@ -106,6 +120,7 @@ export function initMVTRoutes({ requestType: query.requestType as RENDER_AS, geoFieldType: query.geoFieldType as ES_GEO_FIELD_TYPE, searchSessionId: query.searchSessionId, + abortSignal: abortController.signal, }); return sendResponse(response, tile);