DeprecationService: add timeout when resolving deprecations (#125769)

This commit is contained in:
Pierre Gayvallet 2022-02-17 07:49:00 +01:00 committed by GitHub
parent 5b752653f4
commit 24ea50eeb8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 3 deletions

View file

@ -65,6 +65,25 @@ describe('DeprecationsRegistry', () => {
]);
});
it('rejects deprecations when reaching the timeout', async () => {
const deprecationsRegistry = new DeprecationsRegistry({ timeout: 100 });
const mockContext = {} as unknown as GetDeprecationsContext;
const deprecationsConfigA = {
getDeprecations: jest.fn().mockReturnValue(new Promise(() => {})),
};
deprecationsRegistry.registerDeprecations(deprecationsConfigA);
const deprecations = await deprecationsRegistry.getDeprecations(mockContext);
expect(deprecations).toStrictEqual([
{
status: 'rejected',
reason: expect.any(Error),
},
]);
expect((deprecations[0] as PromiseRejectedResult).reason.message).toEqual(
'Deprecations did not resolve in 10sec.'
);
});
it('passes dependencies to registered getDeprecations function', async () => {
const deprecationsRegistry = new DeprecationsRegistry();
const mockContext = {} as unknown as GetDeprecationsContext;

View file

@ -6,15 +6,23 @@
* Side Public License, v 1.
*/
import { withTimeout, isPromise } from '@kbn/std';
import type {
DeprecationsDetails,
RegisterDeprecationsConfig,
GetDeprecationsContext,
} from './types';
const MsInSec = 1000;
export class DeprecationsRegistry {
private readonly timeout: number;
private readonly deprecationContexts: RegisterDeprecationsConfig[] = [];
constructor({ timeout = 10 * MsInSec }: { timeout?: number } = {}) {
this.timeout = timeout;
}
public registerDeprecations = (deprecationContext: RegisterDeprecationsConfig) => {
if (typeof deprecationContext.getDeprecations !== 'function') {
throw new Error(`getDeprecations must be a function in registerDeprecations(context)`);
@ -27,9 +35,21 @@ export class DeprecationsRegistry {
dependencies: GetDeprecationsContext
): Promise<Array<PromiseSettledResult<DeprecationsDetails[]>>> => {
return await Promise.allSettled(
this.deprecationContexts.map(
async (deprecationContext) => await deprecationContext.getDeprecations(dependencies)
)
this.deprecationContexts.map(async (deprecationContext) => {
const maybePromise = deprecationContext.getDeprecations(dependencies);
if (isPromise(maybePromise)) {
const resultOrTimeout = await withTimeout({
promise: maybePromise,
timeoutMs: this.timeout,
});
if (resultOrTimeout.timedout) {
throw new Error('Deprecations did not resolve in 10sec.');
}
return resultOrTimeout.value;
} else {
return maybePromise;
}
})
);
};
}