From 8462fc0aa884ef8690b51bc91e849cf85744191d Mon Sep 17 00:00:00 2001 From: Rudolf Meijering Date: Tue, 3 Mar 2020 09:05:02 +0100 Subject: [PATCH] [7.6] Retry migration operations which fail due to snapshot in progress (#58884) (#59019) * Retry migration operations which fail due to snapshot in progress (#58884) Co-authored-by: Elastic Machine * Import APICaller type Co-authored-by: Elastic Machine --- .../elasticsearch/retry_call_cluster.test.ts | 13 +++++++++++ .../elasticsearch/retry_call_cluster.ts | 22 +++++-------------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/core/server/elasticsearch/retry_call_cluster.test.ts b/src/core/server/elasticsearch/retry_call_cluster.test.ts index b5a5185ab39d9..4f391f0aba34b 100644 --- a/src/core/server/elasticsearch/retry_call_cluster.test.ts +++ b/src/core/server/elasticsearch/retry_call_cluster.test.ts @@ -89,6 +89,19 @@ describe('migrationsRetryCallCluster', () => { }); }); + it('retries ES API calls that rejects with snapshot_in_progress_exception', () => { + expect.assertions(1); + const callEsApi = jest.fn(); + let i = 0; + callEsApi.mockImplementation(() => { + return i++ <= 2 + ? Promise.reject({ body: { error: { type: 'snapshot_in_progress_exception' } } }) + : Promise.resolve('success'); + }); + const retried = migrationsRetryCallCluster(callEsApi, mockLogger.get('mock log'), 1); + return expect(retried('endpoint')).resolves.toMatchInlineSnapshot(`"success"`); + }); + it('rejects when ES API calls reject with other errors', async () => { expect.assertions(3); const callEsApi = jest.fn(); diff --git a/src/core/server/elasticsearch/retry_call_cluster.ts b/src/core/server/elasticsearch/retry_call_cluster.ts index de89f636a9501..e9d6215c94211 100644 --- a/src/core/server/elasticsearch/retry_call_cluster.ts +++ b/src/core/server/elasticsearch/retry_call_cluster.ts @@ -23,6 +23,7 @@ import * as legacyElasticsearch from 'elasticsearch'; import { CallAPIOptions } from '.'; import { Logger } from '../logging'; +import { APICaller } from './api_types'; const esErrors = legacyElasticsearch.errors; @@ -35,14 +36,8 @@ const esErrors = legacyElasticsearch.errors; * * @param apiCaller */ - -// TODO: Replace with APICaller from './scoped_cluster_client' once #46668 is merged export function migrationsRetryCallCluster( - apiCaller: ( - endpoint: string, - clientParams: Record, - options?: CallAPIOptions - ) => Promise, + apiCaller: APICaller, log: Logger, delay: number = 2500 ) { @@ -67,7 +62,8 @@ export function migrationsRetryCallCluster( error instanceof esErrors.AuthenticationException || error instanceof esErrors.AuthorizationException || // @ts-ignore - error instanceof esErrors.Gone + error instanceof esErrors.Gone || + error?.body?.error?.type === 'snapshot_in_progress_exception' ); }, timer(delay), @@ -88,15 +84,7 @@ export function migrationsRetryCallCluster( * * @param apiCaller */ - -// TODO: Replace with APICaller from './scoped_cluster_client' once #46668 is merged -export function retryCallCluster( - apiCaller: ( - endpoint: string, - clientParams: Record, - options?: CallAPIOptions - ) => Promise -) { +export function retryCallCluster(apiCaller: APICaller) { return (endpoint: string, clientParams: Record = {}, options?: CallAPIOptions) => { return defer(() => apiCaller(endpoint, clientParams, options)) .pipe(