From 8d1d280655f77d4fe9cee13036ab0ef8282174c5 Mon Sep 17 00:00:00 2001 From: Nikolay Matrosov Date: Mon, 13 Feb 2023 15:39:57 +0100 Subject: [PATCH] feat: add retry middleware & configure retries in waitForOperation utility function --- package-lock.json | 61 ++++++++++++++++++++++++++++----- package.json | 1 + src/types.ts | 14 +++++--- src/utils/client-factory.ts | 5 ++- src/utils/operation/wait-for.ts | 11 ++++-- 5 files changed, 77 insertions(+), 15 deletions(-) diff --git a/package-lock.json b/package-lock.json index 41719282..1cb511ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "luxon": "^2.2.0", "nice-grpc": "^1.0.6", "nice-grpc-client-middleware-deadline": "^1.0.6", + "nice-grpc-client-middleware-retry": "^1.1.2", "protobufjs": "^6.11.3", "utility-types": "^3.10.0" }, @@ -7352,14 +7353,30 @@ "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-2.0.0.tgz", "integrity": "sha512-L8RfEgjBTHAISTuagw51PprVAqNZoG6KSB6LQ6H1bskMVkFs5E71IyjauLBv3XbuomJlguWF/VnRHdJ1gqiAqA==" }, - "node_modules/nice-grpc-common": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/nice-grpc-common/-/nice-grpc-common-1.0.4.tgz", - "integrity": "sha512-cpKGONNYqi2XP+5z4B4bzhLNrJu5lPbIScM0sqsht6sG9TgdN7ws3qCH82Fht94CfOifL6pQlvkgnEJp5nl2cQ==", + "node_modules/nice-grpc-client-middleware-retry": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/nice-grpc-client-middleware-retry/-/nice-grpc-client-middleware-retry-1.1.2.tgz", + "integrity": "sha512-7RWHpQxQ6Dq++TTaP/S/GFd4MuSd1jjeQr8q41oQ6phyPRTZmNx8gdbVQg2Q70iATFjJ9eQfj4/QysfeQ3LURQ==", "dependencies": { + "abort-controller-x": "^0.2.6", + "nice-grpc-common": "^1.1.0", "node-abort-controller": "^2.0.0" } }, + "node_modules/nice-grpc-client-middleware-retry/node_modules/node-abort-controller": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-2.0.0.tgz", + "integrity": "sha512-L8RfEgjBTHAISTuagw51PprVAqNZoG6KSB6LQ6H1bskMVkFs5E71IyjauLBv3XbuomJlguWF/VnRHdJ1gqiAqA==" + }, + "node_modules/nice-grpc-common": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/nice-grpc-common/-/nice-grpc-common-1.1.0.tgz", + "integrity": "sha512-klxJ/lxMyH1KkT02woMBWL3A7BQSTH5jGodJIpNbbv7WKeFBWJaEtT6p7kZJBhGYXtSsQ+TyMU1EJR9BH14YfQ==", + "dependencies": { + "node-abort-controller": "^2.0.0", + "ts-error": "^1.0.6" + } + }, "node_modules/nice-grpc-common/node_modules/node-abort-controller": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-2.0.0.tgz", @@ -11613,6 +11630,11 @@ "node": ">=8" } }, + "node_modules/ts-error": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/ts-error/-/ts-error-1.0.6.tgz", + "integrity": "sha512-tLJxacIQUM82IR7JO1UUkKlYuUTmoY9HBJAmNWFzheSlDS5SPMcNIepejHJa4BpPQLAcbRhRf3GDJzyj6rbKvA==" + }, "node_modules/ts-jest": { "version": "27.1.1", "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.1.tgz", @@ -17913,11 +17935,13 @@ } } }, - "nice-grpc-common": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/nice-grpc-common/-/nice-grpc-common-1.0.4.tgz", - "integrity": "sha512-cpKGONNYqi2XP+5z4B4bzhLNrJu5lPbIScM0sqsht6sG9TgdN7ws3qCH82Fht94CfOifL6pQlvkgnEJp5nl2cQ==", + "nice-grpc-client-middleware-retry": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/nice-grpc-client-middleware-retry/-/nice-grpc-client-middleware-retry-1.1.2.tgz", + "integrity": "sha512-7RWHpQxQ6Dq++TTaP/S/GFd4MuSd1jjeQr8q41oQ6phyPRTZmNx8gdbVQg2Q70iATFjJ9eQfj4/QysfeQ3LURQ==", "requires": { + "abort-controller-x": "^0.2.6", + "nice-grpc-common": "^1.1.0", "node-abort-controller": "^2.0.0" }, "dependencies": { @@ -17928,6 +17952,22 @@ } } }, + "nice-grpc-common": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/nice-grpc-common/-/nice-grpc-common-1.1.0.tgz", + "integrity": "sha512-klxJ/lxMyH1KkT02woMBWL3A7BQSTH5jGodJIpNbbv7WKeFBWJaEtT6p7kZJBhGYXtSsQ+TyMU1EJR9BH14YfQ==", + "requires": { + "node-abort-controller": "^2.0.0", + "ts-error": "^1.0.6" + }, + "dependencies": { + "node-abort-controller": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-2.0.0.tgz", + "integrity": "sha512-L8RfEgjBTHAISTuagw51PprVAqNZoG6KSB6LQ6H1bskMVkFs5E71IyjauLBv3XbuomJlguWF/VnRHdJ1gqiAqA==" + } + } + }, "node-abort-controller": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-1.2.1.tgz", @@ -20998,6 +21038,11 @@ "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", "dev": true }, + "ts-error": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/ts-error/-/ts-error-1.0.6.tgz", + "integrity": "sha512-tLJxacIQUM82IR7JO1UUkKlYuUTmoY9HBJAmNWFzheSlDS5SPMcNIepejHJa4BpPQLAcbRhRf3GDJzyj6rbKvA==" + }, "ts-jest": { "version": "27.1.1", "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.1.tgz", diff --git a/package.json b/package.json index eb12599b..1f40be95 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "luxon": "^2.2.0", "nice-grpc": "^1.0.6", "nice-grpc-client-middleware-deadline": "^1.0.6", + "nice-grpc-client-middleware-retry": "^1.1.2", "protobufjs": "^6.11.3", "utility-types": "^3.10.0" }, diff --git a/src/types.ts b/src/types.ts index 6fa69b58..c78baae0 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,21 +1,26 @@ import { - ChannelCredentials, ChannelOptions, Client, ServiceDefinition, + ChannelCredentials, + ChannelOptions, + Client, + ServiceDefinition, } from '@grpc/grpc-js'; import { RawClient } from 'nice-grpc'; -import { NormalizedServiceDefinition } from 'nice-grpc/lib/service-definitions'; import { DeadlineOptions } from 'nice-grpc-client-middleware-deadline'; +import { RetryOptions } from 'nice-grpc-client-middleware-retry'; +import { NormalizedServiceDefinition } from 'nice-grpc/lib/service-definitions'; export interface TokenService { getToken: () => Promise; } export interface GeneratedServiceClientCtor { + service: T + new( address: string, credentials: ChannelCredentials, options?: Partial, ): Client; - service: T } export interface IIAmCredentials { @@ -59,4 +64,5 @@ export type SessionConfig = | ServiceAccountCredentialsConfig | GenericCredentialsConfig; -export type WrappedServiceClientType = RawClient, DeadlineOptions>; +// eslint-disable-next-line max-len +export type WrappedServiceClientType = RawClient, DeadlineOptions & RetryOptions>; diff --git a/src/utils/client-factory.ts b/src/utils/client-factory.ts index 86a1d26c..57e4cc96 100644 --- a/src/utils/client-factory.ts +++ b/src/utils/client-factory.ts @@ -1,4 +1,7 @@ import { createClientFactory } from 'nice-grpc'; import { deadlineMiddleware } from 'nice-grpc-client-middleware-deadline'; +import { retryMiddleware } from 'nice-grpc-client-middleware-retry'; -export const clientFactory = createClientFactory().use(deadlineMiddleware); +export const clientFactory = createClientFactory() + .use(retryMiddleware) + .use(deadlineMiddleware); diff --git a/src/utils/operation/wait-for.ts b/src/utils/operation/wait-for.ts index bafdc384..fb9ad558 100644 --- a/src/utils/operation/wait-for.ts +++ b/src/utils/operation/wait-for.ts @@ -1,6 +1,9 @@ -import { Session } from '../../session'; +import { + cloudApi, + serviceClients, +} from '../..'; import { Operation } from '../../generated/yandex/cloud/operation/operation'; -import { serviceClients, cloudApi } from '../..'; +import { Session } from '../../session'; const { operation: { operation_service: { GetOperationRequest } } } = cloudApi; @@ -18,6 +21,10 @@ export const waitForOperation = (op: Operation, session: Session, timeoutMs: num GetOperationRequest.fromPartial({ operationId: op.id, }), + { + retry: true, + retryMaxAttempts: 3, + }, ); checksCount++;