diff --git a/package-lock.json b/package-lock.json index cf7eeff6..4ef050c3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17679,6 +17679,15 @@ "nice-grpc-common": "^2.0.2" } }, + "node_modules/nice-grpc-client-middleware-retry": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/nice-grpc-client-middleware-retry/-/nice-grpc-client-middleware-retry-3.1.7.tgz", + "integrity": "sha512-mof78LIcOZV53UuzyBp9Hr0VONNCRCepoZ4NLwz8CscolI8ABOby+SjNan88+KpzgPQzzZtKLzAYieGwWT1nCQ==", + "dependencies": { + "abort-controller-x": "^0.4.0", + "nice-grpc-common": "^2.0.2" + } + }, "node_modules/nice-grpc-common": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/nice-grpc-common/-/nice-grpc-common-2.0.2.tgz", @@ -27152,6 +27161,7 @@ "lodash": "^4.17.21", "nice-grpc": "^2.1.7", "nice-grpc-client-middleware-deadline": "^2.0.10", + "nice-grpc-client-middleware-retry": "^3.1.7", "protobufjs": "^7.2.6", "retry": "^0.13.1", "rxjs": "^7.8.1", diff --git a/packages/grpc-client/package.json b/packages/grpc-client/package.json index b9968ef4..82c7b383 100644 --- a/packages/grpc-client/package.json +++ b/packages/grpc-client/package.json @@ -23,6 +23,7 @@ "lodash": "^4.17.21", "nice-grpc": "^2.1.7", "nice-grpc-client-middleware-deadline": "^2.0.10", + "nice-grpc-client-middleware-retry": "^3.1.7", "protobufjs": "^7.2.6", "retry": "^0.13.1", "rxjs": "^7.8.1", diff --git a/packages/grpc-client/src/index.ts b/packages/grpc-client/src/index.ts index 8513fea1..b66d2654 100644 --- a/packages/grpc-client/src/index.ts +++ b/packages/grpc-client/src/index.ts @@ -4,6 +4,7 @@ import { createClientFactory as createClientFactoryInternal, DefaultCallOptions, createChannel, + ClientError, } from 'nice-grpc'; import { CompatServiceDefinition, NormalizedServiceDefinition } from 'nice-grpc/lib/service-definitions'; import { @@ -15,6 +16,7 @@ import { } from './middleware'; import { createLogger } from '@restorecommerce/logger'; import { deadlineMiddleware } from 'nice-grpc-client-middleware-deadline'; +import { retryMiddleware } from 'nice-grpc-client-middleware-retry'; export interface GrpcClientConfig { logger: ReturnType; @@ -31,13 +33,26 @@ export function createClient( let factory = createClientFactoryInternal() .use(loggingMiddleware(config.logger, config.omittedFields)) .use(tracingMiddleware) - .use(metaMiddleware); + .use(metaMiddleware) + .use(retryMiddleware); if (config.timeout) { factory = factory.use(deadlineMiddleware); factory = factory.use(internalDeadlineMiddleware(config.timeout)); } + if (!defaultCallOptions) { + defaultCallOptions = {}; + } + defaultCallOptions = Object.assign(defaultCallOptions, { + '*': { + retryMaxAttempts: 5, + retry: true, + }, + onRetryableError(error: ClientError, attempt: number, delayMs: number) { + config.logger.error(`Call failed (${attempt}), retrying in ${delayMs}ms`, { code: error.code, message: error.message, stack: error.stack }); + } + }); return factory.create(definition, channel, defaultCallOptions); }