From 6b62ec0f3d100e880eb4d008ed5ac727cba538ae Mon Sep 17 00:00:00 2001 From: Sri Krishna Paritala Date: Fri, 29 Sep 2023 16:27:33 +0530 Subject: [PATCH 1/4] Add support for graceful shutdown in fastify --- .../src/fastify-connect-plugin.ts | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/packages/connect-fastify/src/fastify-connect-plugin.ts b/packages/connect-fastify/src/fastify-connect-plugin.ts index 8200fa2ff..d71381c23 100644 --- a/packages/connect-fastify/src/fastify-connect-plugin.ts +++ b/packages/connect-fastify/src/fastify-connect-plugin.ts @@ -14,6 +14,7 @@ import type { JsonValue } from "@bufbuild/protobuf"; import { Code, ConnectError, createConnectRouter } from "@connectrpc/connect"; +import { createLinkedAbortController } from "@connectrpc/connect/protocol"; import type { ConnectRouter, ConnectRouterOptions } from "@connectrpc/connect"; import * as protoConnect from "@connectrpc/connect/protocol-connect"; import * as protoGrpcWeb from "@connectrpc/connect/protocol-grpc-web"; @@ -43,6 +44,17 @@ interface FastifyConnectPluginOptions extends ConnectRouterOptions { * Then pass this function here. */ routes?: (router: ConnectRouter) => void; + + /** + * If set, once `fastify.close` is called, waits for the requests to be finished for the specified duration + * before aborting them. + */ + shutdownTimeout?: number; + + /** + * The error to be returned for requests that couldn't complete within the shutdown period. + */ + shutdownError?: unknown; } /** @@ -60,6 +72,19 @@ export function fastifyConnectPlugin( if (opts.acceptCompression === undefined) { opts.acceptCompression = [compressionGzip, compressionBrotli]; } + if (opts.shutdownTimeout !== undefined) { + const shutdownController = createLinkedAbortController(opts.shutdownSignal); + opts.shutdownSignal = shutdownController.signal; + instance.addHook("preClose", (done) => { + setTimeout(() => { + shutdownController.abort( + opts.shutdownError ?? + new ConnectError("The request was aborted", Code.Aborted), + ); + }, opts.shutdownTimeout); + done(); + }); + } const router = createConnectRouter(opts); opts.routes(router); From 90b49a93254bf5f58a8dcb9c25732b2ccc7284a5 Mon Sep 17 00:00:00 2001 From: Sri Krishna Paritala Date: Fri, 29 Sep 2023 16:36:26 +0530 Subject: [PATCH 2/4] Add note about default error --- packages/connect-fastify/src/fastify-connect-plugin.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/connect-fastify/src/fastify-connect-plugin.ts b/packages/connect-fastify/src/fastify-connect-plugin.ts index d71381c23..fb7d5c3cc 100644 --- a/packages/connect-fastify/src/fastify-connect-plugin.ts +++ b/packages/connect-fastify/src/fastify-connect-plugin.ts @@ -53,6 +53,8 @@ interface FastifyConnectPluginOptions extends ConnectRouterOptions { /** * The error to be returned for requests that couldn't complete within the shutdown period. + * + * Defaults to a ConnectError with code `Code.Aborted`. */ shutdownError?: unknown; } From b2edbb329336b24d890169d85d7c34cd25a93b2c Mon Sep 17 00:00:00 2001 From: Sri Krishna Paritala Date: Fri, 29 Sep 2023 16:38:39 +0530 Subject: [PATCH 3/4] Unit suffix --- packages/connect-fastify/src/fastify-connect-plugin.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/connect-fastify/src/fastify-connect-plugin.ts b/packages/connect-fastify/src/fastify-connect-plugin.ts index fb7d5c3cc..8c970f3e2 100644 --- a/packages/connect-fastify/src/fastify-connect-plugin.ts +++ b/packages/connect-fastify/src/fastify-connect-plugin.ts @@ -49,7 +49,7 @@ interface FastifyConnectPluginOptions extends ConnectRouterOptions { * If set, once `fastify.close` is called, waits for the requests to be finished for the specified duration * before aborting them. */ - shutdownTimeout?: number; + shutdownTimeoutMs?: number; /** * The error to be returned for requests that couldn't complete within the shutdown period. @@ -74,7 +74,7 @@ export function fastifyConnectPlugin( if (opts.acceptCompression === undefined) { opts.acceptCompression = [compressionGzip, compressionBrotli]; } - if (opts.shutdownTimeout !== undefined) { + if (opts.shutdownTimeoutMs !== undefined) { const shutdownController = createLinkedAbortController(opts.shutdownSignal); opts.shutdownSignal = shutdownController.signal; instance.addHook("preClose", (done) => { @@ -83,7 +83,7 @@ export function fastifyConnectPlugin( opts.shutdownError ?? new ConnectError("The request was aborted", Code.Aborted), ); - }, opts.shutdownTimeout); + }, opts.shutdownTimeoutMs); done(); }); } From ee496a9d8e64392bda155def160fe485bb739a9d Mon Sep 17 00:00:00 2001 From: Sri Krishna Paritala Date: Fri, 29 Sep 2023 17:01:01 +0530 Subject: [PATCH 4/4] change error default --- .../connect-fastify/src/fastify-connect-plugin.ts | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/packages/connect-fastify/src/fastify-connect-plugin.ts b/packages/connect-fastify/src/fastify-connect-plugin.ts index 8c970f3e2..d21f1367f 100644 --- a/packages/connect-fastify/src/fastify-connect-plugin.ts +++ b/packages/connect-fastify/src/fastify-connect-plugin.ts @@ -52,9 +52,9 @@ interface FastifyConnectPluginOptions extends ConnectRouterOptions { shutdownTimeoutMs?: number; /** - * The error to be returned for requests that couldn't complete within the shutdown period. - * - * Defaults to a ConnectError with code `Code.Aborted`. + * The abort error caused by the shutdown timeout. + * + * If this is a ConnectError, it will be sent to the client. */ shutdownError?: unknown; } @@ -79,10 +79,7 @@ export function fastifyConnectPlugin( opts.shutdownSignal = shutdownController.signal; instance.addHook("preClose", (done) => { setTimeout(() => { - shutdownController.abort( - opts.shutdownError ?? - new ConnectError("The request was aborted", Code.Aborted), - ); + shutdownController.abort(opts.shutdownError); }, opts.shutdownTimeoutMs); done(); });