From c24353cc24ebf4b40ff9a2cec8e37cfdef109e37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karol=20S=C3=B3jko?= Date: Fri, 10 Nov 2023 12:20:21 +0100 Subject: [PATCH] feat: add graceful shutdown procedures upon SIGTERM (#923) --- packages/analytics/bin/worker.ts | 6 ++++ packages/analytics/docker/entrypoint.sh | 4 +-- packages/api-gateway/bin/server.ts | 7 +++++ packages/api-gateway/docker/entrypoint.sh | 2 +- .../supervisor/supervisor-server.sh | 2 +- packages/auth/bin/server.ts | 9 ++++-- packages/auth/bin/worker.ts | 6 ++++ packages/auth/docker/entrypoint.sh | 16 +++++----- packages/auth/supervisor/supervisor-server.sh | 2 +- packages/auth/supervisor/supervisor-worker.sh | 2 +- .../Redis/RedisDomainEventSubscriber.spec.ts | 23 -------------- .../Infra/Redis/RedisDomainEventSubscriber.ts | 14 --------- .../RedisDomainEventSubscriberFactory.spec.ts | 31 ------------------- .../RedisDomainEventSubscriberFactory.ts | 29 ----------------- .../src/Infra/SQS/SQSDomainEventSubscriber.ts | 11 +++++++ .../SQSOpenTelemetryDomainEventSubscriber.ts | 10 ++++++ .../domain-events-infra/src/Infra/index.ts | 2 -- .../DomainEventSubscriberInterface.ts | 1 + packages/event-store/docker/entrypoint.sh | 2 +- packages/files/bin/server.ts | 9 ++++-- packages/files/bin/worker.ts | 6 ++++ packages/files/docker/entrypoint.sh | 4 +-- .../files/supervisor/supervisor-server.sh | 2 +- .../files/supervisor/supervisor-worker.sh | 2 +- packages/home-server/src/Server/HomeServer.ts | 11 ++++++- packages/revisions/bin/server.ts | 9 ++++-- packages/revisions/bin/worker.ts | 6 ++++ packages/revisions/docker/entrypoint.sh | 4 +-- .../revisions/supervisor/supervisor-server.sh | 2 +- .../revisions/supervisor/supervisor-worker.sh | 2 +- packages/scheduler/bin/worker.ts | 6 ++++ packages/scheduler/docker/entrypoint.sh | 4 +-- packages/syncing-server/bin/server.ts | 9 ++++-- packages/syncing-server/bin/worker.ts | 6 ++++ packages/syncing-server/docker/entrypoint.sh | 4 +-- .../supervisor/supervisor-server.sh | 2 +- .../supervisor/supervisor-worker.sh | 2 +- packages/websockets/bin/server.ts | 9 ++++-- packages/websockets/bin/worker.ts | 6 ++++ packages/websockets/docker/entrypoint.sh | 4 +-- 40 files changed, 147 insertions(+), 141 deletions(-) delete mode 100644 packages/domain-events-infra/src/Infra/Redis/RedisDomainEventSubscriber.spec.ts delete mode 100644 packages/domain-events-infra/src/Infra/Redis/RedisDomainEventSubscriber.ts delete mode 100644 packages/domain-events-infra/src/Infra/Redis/RedisDomainEventSubscriberFactory.spec.ts delete mode 100644 packages/domain-events-infra/src/Infra/Redis/RedisDomainEventSubscriberFactory.ts diff --git a/packages/analytics/bin/worker.ts b/packages/analytics/bin/worker.ts index a09406d9b..b814e9d4e 100644 --- a/packages/analytics/bin/worker.ts +++ b/packages/analytics/bin/worker.ts @@ -22,5 +22,11 @@ void container.load().then((container) => { const subscriber = container.get(TYPES.DomainEventSubscriber) + process.on('SIGTERM', () => { + logger.info('SIGTERM received. Stopping worker...') + subscriber.stop() + logger.info('Worker stopped.') + }) + subscriber.start() }) diff --git a/packages/analytics/docker/entrypoint.sh b/packages/analytics/docker/entrypoint.sh index b68ea6d10..56a9867e5 100755 --- a/packages/analytics/docker/entrypoint.sh +++ b/packages/analytics/docker/entrypoint.sh @@ -6,12 +6,12 @@ COMMAND=$1 && shift 1 case "$COMMAND" in 'start-worker' ) echo "[Docker] Starting Worker..." - node docker/entrypoint-worker.js + exec node docker/entrypoint-worker.js ;; 'report' ) echo "[Docker] Starting Usage Report Generation..." - node docker/entrypoint-report.js + exec node docker/entrypoint-report.js ;; * ) diff --git a/packages/api-gateway/bin/server.ts b/packages/api-gateway/bin/server.ts index c5aaa9903..a57a03bcb 100644 --- a/packages/api-gateway/bin/server.ts +++ b/packages/api-gateway/bin/server.ts @@ -108,5 +108,12 @@ void container.load().then((container) => { serverInstance.keepAliveTimeout = keepAliveTimeout + process.on('SIGTERM', () => { + logger.info('SIGTERM signal received: closing HTTP server') + serverInstance.close(() => { + logger.info('HTTP server closed') + }) + }) + logger.info(`Server started on port ${process.env.PORT}`) }) diff --git a/packages/api-gateway/docker/entrypoint.sh b/packages/api-gateway/docker/entrypoint.sh index fe2c3544d..2d850a2e4 100755 --- a/packages/api-gateway/docker/entrypoint.sh +++ b/packages/api-gateway/docker/entrypoint.sh @@ -6,7 +6,7 @@ COMMAND=$1 && shift 1 case "$COMMAND" in 'start-web' ) echo "Starting Web..." - node docker/entrypoint-server.js + exec node docker/entrypoint-server.js ;; * ) diff --git a/packages/api-gateway/supervisor/supervisor-server.sh b/packages/api-gateway/supervisor/supervisor-server.sh index b541c90cc..b003aeba0 100755 --- a/packages/api-gateway/supervisor/supervisor-server.sh +++ b/packages/api-gateway/supervisor/supervisor-server.sh @@ -6,4 +6,4 @@ sh supervisor/wait-for.sh localhost $AUTH_SERVER_PORT sh supervisor/wait-for.sh localhost $FILES_SERVER_PORT sh supervisor/wait-for.sh localhost $REVISIONS_SERVER_PORT sh supervisor/wait-for.sh localhost $SYNCING_SERVER_PORT -node docker/entrypoint-server.js +exec node docker/entrypoint-server.js diff --git a/packages/auth/bin/server.ts b/packages/auth/bin/server.ts index 39d27a297..5c634b0de 100644 --- a/packages/auth/bin/server.ts +++ b/packages/auth/bin/server.ts @@ -64,9 +64,14 @@ void container.load().then((container) => { }) }) - const serverInstance = server.build() + const serverInstance = server.build().listen(env.get('PORT')) - serverInstance.listen(env.get('PORT')) + process.on('SIGTERM', () => { + logger.info('SIGTERM signal received: closing HTTP server') + serverInstance.close(() => { + logger.info('HTTP server closed') + }) + }) logger.info(`Server started on port ${process.env.PORT}`) }) diff --git a/packages/auth/bin/worker.ts b/packages/auth/bin/worker.ts index 29d86acfb..728acc8a4 100644 --- a/packages/auth/bin/worker.ts +++ b/packages/auth/bin/worker.ts @@ -22,5 +22,11 @@ void container.load().then((container) => { const subscriber = container.get(TYPES.Auth_DomainEventSubscriber) + process.on('SIGTERM', () => { + logger.info('SIGTERM received. Stopping worker...') + subscriber.stop() + logger.info('Worker stopped.') + }) + subscriber.start() }) diff --git a/packages/auth/docker/entrypoint.sh b/packages/auth/docker/entrypoint.sh index 73d0d715f..dd5b7d94e 100755 --- a/packages/auth/docker/entrypoint.sh +++ b/packages/auth/docker/entrypoint.sh @@ -6,45 +6,45 @@ COMMAND=$1 && shift 1 case "$COMMAND" in 'start-web' ) echo "[Docker] Starting Web..." - node docker/entrypoint-server.js + exec node docker/entrypoint-server.js ;; 'start-worker' ) echo "[Docker] Starting Worker..." - node docker/entrypoint-worker.js + exec node docker/entrypoint-worker.js ;; 'cleanup' ) echo "[Docker] Starting Cleanup..." - node docker/entrypoint-cleanup.js + exec node docker/entrypoint-cleanup.js ;; 'stats' ) echo "[Docker] Starting Persisting Stats..." - node docker/entrypoint-stats.js + exec node docker/entrypoint-stats.js ;; 'email-daily-backup' ) echo "[Docker] Starting Email Daily Backup..." - node docker/entrypoint-backup.js daily + exec node docker/entrypoint-backup.js daily ;; 'email-weekly-backup' ) echo "[Docker] Starting Email Weekly Backup..." - node docker/entrypoint-backup.js weekly + exec node docker/entrypoint-backup.js weekly ;; 'email-backup' ) echo "[Docker] Starting Email Backup For Single User..." EMAIL=$1 && shift 1 - node docker/entrypoint-user-email-backup.js $EMAIL + exec node docker/entrypoint-user-email-backup.js $EMAIL ;; 'delete-accounts' ) echo "[Docker] Starting Accounts Deleting from CSV..." FILE_NAME=$1 && shift 1 MODE=$1 && shift 1 - node docker/entrypoint-delete-accounts.js $FILE_NAME $MODE + exec node docker/entrypoint-delete-accounts.js $FILE_NAME $MODE ;; * ) diff --git a/packages/auth/supervisor/supervisor-server.sh b/packages/auth/supervisor/supervisor-server.sh index 7a0b602f9..77f825b23 100755 --- a/packages/auth/supervisor/supervisor-server.sh +++ b/packages/auth/supervisor/supervisor-server.sh @@ -3,4 +3,4 @@ set -euo pipefail sh supervisor/wait-for.sh localhost $SYNCING_SERVER_PORT -node docker/entrypoint-server.js +exec node docker/entrypoint-server.js diff --git a/packages/auth/supervisor/supervisor-worker.sh b/packages/auth/supervisor/supervisor-worker.sh index e26e18147..b6398ef80 100755 --- a/packages/auth/supervisor/supervisor-worker.sh +++ b/packages/auth/supervisor/supervisor-worker.sh @@ -3,4 +3,4 @@ set -euo pipefail sh supervisor/wait-for.sh localhost $AUTH_SERVER_PORT -node docker/entrypoint-worker.js +exec node docker/entrypoint-worker.js diff --git a/packages/domain-events-infra/src/Infra/Redis/RedisDomainEventSubscriber.spec.ts b/packages/domain-events-infra/src/Infra/Redis/RedisDomainEventSubscriber.spec.ts deleted file mode 100644 index 3605f7250..000000000 --- a/packages/domain-events-infra/src/Infra/Redis/RedisDomainEventSubscriber.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import 'reflect-metadata' - -import * as IORedis from 'ioredis' - -import { RedisDomainEventSubscriber } from './RedisDomainEventSubscriber' - -describe('RedisDomainEventSubscriber', () => { - let redisClient: IORedis.Redis - const eventChannel = 'test-channel' - - const createSubscriber = () => new RedisDomainEventSubscriber(redisClient, eventChannel) - - beforeEach(() => { - redisClient = {} as jest.Mocked - redisClient.subscribe = jest.fn() - }) - - it('should start the subscription', () => { - createSubscriber().start() - - expect(redisClient.subscribe).toHaveBeenCalledWith('test-channel') - }) -}) diff --git a/packages/domain-events-infra/src/Infra/Redis/RedisDomainEventSubscriber.ts b/packages/domain-events-infra/src/Infra/Redis/RedisDomainEventSubscriber.ts deleted file mode 100644 index a776e89a8..000000000 --- a/packages/domain-events-infra/src/Infra/Redis/RedisDomainEventSubscriber.ts +++ /dev/null @@ -1,14 +0,0 @@ -import * as IORedis from 'ioredis' - -import { DomainEventSubscriberInterface } from '@standardnotes/domain-events' - -export class RedisDomainEventSubscriber implements DomainEventSubscriberInterface { - constructor( - private redisClient: IORedis.Redis, - private eventChannel: string, - ) {} - - start(): void { - void this.redisClient.subscribe(this.eventChannel) - } -} diff --git a/packages/domain-events-infra/src/Infra/Redis/RedisDomainEventSubscriberFactory.spec.ts b/packages/domain-events-infra/src/Infra/Redis/RedisDomainEventSubscriberFactory.spec.ts deleted file mode 100644 index 39503a4ab..000000000 --- a/packages/domain-events-infra/src/Infra/Redis/RedisDomainEventSubscriberFactory.spec.ts +++ /dev/null @@ -1,31 +0,0 @@ -import 'reflect-metadata' - -import * as IORedis from 'ioredis' - -import { RedisDomainEventSubscriberFactory } from './RedisDomainEventSubscriberFactory' -import { DomainEventMessageHandlerInterface } from '@standardnotes/domain-events' -import { RedisDomainEventSubscriber } from './RedisDomainEventSubscriber' - -describe('RedisDomainEventSubscriberFactory', () => { - let redisClient: IORedis.Redis - let domainEventMessageHandler: DomainEventMessageHandlerInterface - const eventChannel = 'events' - - const createFactory = () => - new RedisDomainEventSubscriberFactory(redisClient, domainEventMessageHandler, eventChannel) - - beforeEach(() => { - redisClient = {} as jest.Mocked - redisClient.on = jest.fn() - - domainEventMessageHandler = {} as jest.Mocked - domainEventMessageHandler.handleMessage = jest.fn() - }) - - it('should create an event subscriber', () => { - const subscriber = createFactory().create() - - expect(subscriber).toBeInstanceOf(RedisDomainEventSubscriber) - expect(redisClient.on).toHaveBeenCalledWith('message', expect.any(Function)) - }) -}) diff --git a/packages/domain-events-infra/src/Infra/Redis/RedisDomainEventSubscriberFactory.ts b/packages/domain-events-infra/src/Infra/Redis/RedisDomainEventSubscriberFactory.ts deleted file mode 100644 index 9f89bcce7..000000000 --- a/packages/domain-events-infra/src/Infra/Redis/RedisDomainEventSubscriberFactory.ts +++ /dev/null @@ -1,29 +0,0 @@ -import * as IORedis from 'ioredis' - -import { - DomainEventSubscriberFactoryInterface, - DomainEventSubscriberInterface, - DomainEventMessageHandlerInterface, -} from '@standardnotes/domain-events' - -import { RedisDomainEventSubscriber } from './RedisDomainEventSubscriber' - -export class RedisDomainEventSubscriberFactory implements DomainEventSubscriberFactoryInterface { - constructor( - private redisClient: IORedis.Redis, - private domainEventMessageHandler: DomainEventMessageHandlerInterface, - private eventChannel: string, - ) {} - - create(): DomainEventSubscriberInterface { - const subscriber = new RedisDomainEventSubscriber(this.redisClient, this.eventChannel) - - this.redisClient.on( - 'message', - /* istanbul ignore next */ - async (_channel: string, message: string) => await this.domainEventMessageHandler.handleMessage(message), - ) - - return subscriber - } -} diff --git a/packages/domain-events-infra/src/Infra/SQS/SQSDomainEventSubscriber.ts b/packages/domain-events-infra/src/Infra/SQS/SQSDomainEventSubscriber.ts index e48f67d93..d33708ac0 100644 --- a/packages/domain-events-infra/src/Infra/SQS/SQSDomainEventSubscriber.ts +++ b/packages/domain-events-infra/src/Infra/SQS/SQSDomainEventSubscriber.ts @@ -4,6 +4,8 @@ import { DomainEventSubscriberInterface, DomainEventMessageHandlerInterface } fr import { Logger } from 'winston' export class SQSDomainEventSubscriber implements DomainEventSubscriberInterface { + private consumer: Consumer | undefined + constructor( private sqs: SQSClient, private queueUrl: string, @@ -23,9 +25,18 @@ export class SQSDomainEventSubscriber implements DomainEventSubscriberInterface sqsConsumer.on('error', this.handleError.bind(this)) sqsConsumer.on('processing_error', this.handleError.bind(this)) + this.consumer = sqsConsumer + sqsConsumer.start() } + stop(): void { + if (this.consumer && this.consumer.isRunning) { + this.logger.info('Stopping SQS consumer...') + this.consumer.stop() + } + } + async handleMessage(message: Message): Promise { await this.domainEventMessageHandler.handleMessage(message.Body) } diff --git a/packages/domain-events-infra/src/Infra/SQS/SQSOpenTelemetryDomainEventSubscriber.ts b/packages/domain-events-infra/src/Infra/SQS/SQSOpenTelemetryDomainEventSubscriber.ts index 78cb79300..deb3cf3f2 100644 --- a/packages/domain-events-infra/src/Infra/SQS/SQSOpenTelemetryDomainEventSubscriber.ts +++ b/packages/domain-events-infra/src/Infra/SQS/SQSOpenTelemetryDomainEventSubscriber.ts @@ -5,6 +5,7 @@ import { DomainEventSubscriberInterface, DomainEventMessageHandlerInterface } fr import { Logger } from 'winston' export class SQSOpenTelemetryDomainEventSubscriber implements DomainEventSubscriberInterface { + private consumer: Consumer | undefined private currentSpan: OpenTelemetryApi.Span | undefined constructor( @@ -28,9 +29,18 @@ export class SQSOpenTelemetryDomainEventSubscriber implements DomainEventSubscri sqsConsumer.on('error', this.handleError.bind(this)) sqsConsumer.on('processing_error', this.handleError.bind(this)) + this.consumer = sqsConsumer + sqsConsumer.start() } + stop(): void { + if (this.consumer && this.consumer.isRunning) { + this.logger.info('Stopping SQS consumer...') + this.consumer.stop() + } + } + async startParentSpan(): Promise { const tracer = OpenTelemetryApi.trace.getTracer(`${this.serviceName}-domain-event-subscriber`) diff --git a/packages/domain-events-infra/src/Infra/index.ts b/packages/domain-events-infra/src/Infra/index.ts index 9adabaa51..bc21c3266 100644 --- a/packages/domain-events-infra/src/Infra/index.ts +++ b/packages/domain-events-infra/src/Infra/index.ts @@ -7,8 +7,6 @@ export * from './OpenTelemetry/OpenTelemetryTracer' export * from './OpenTelemetry/OpenTelemetryTracerInterface' export * from './Redis/RedisDomainEventPublisher' -export * from './Redis/RedisDomainEventSubscriber' -export * from './Redis/RedisDomainEventSubscriberFactory' export * from './Redis/RedisEventMessageHandler' export * from './SNS/SNSDomainEventPublisher' diff --git a/packages/domain-events/src/Domain/Subscriber/DomainEventSubscriberInterface.ts b/packages/domain-events/src/Domain/Subscriber/DomainEventSubscriberInterface.ts index eef346774..575b5a87d 100644 --- a/packages/domain-events/src/Domain/Subscriber/DomainEventSubscriberInterface.ts +++ b/packages/domain-events/src/Domain/Subscriber/DomainEventSubscriberInterface.ts @@ -1,3 +1,4 @@ export interface DomainEventSubscriberInterface { start(): void + stop(): void } diff --git a/packages/event-store/docker/entrypoint.sh b/packages/event-store/docker/entrypoint.sh index fe09b3188..dfa84c262 100755 --- a/packages/event-store/docker/entrypoint.sh +++ b/packages/event-store/docker/entrypoint.sh @@ -6,7 +6,7 @@ COMMAND=$1 && shift 1 case "$COMMAND" in 'start-worker' ) echo "Starting Worker..." - node docker/entrypoint-worker.js + exec node docker/entrypoint-worker.js ;; * ) diff --git a/packages/files/bin/server.ts b/packages/files/bin/server.ts index 7ebb83ae8..4d1033e18 100644 --- a/packages/files/bin/server.ts +++ b/packages/files/bin/server.ts @@ -89,9 +89,14 @@ void container.load().then((container) => { }) }) - const serverInstance = server.build() + const serverInstance = server.build().listen(env.get('PORT')) - serverInstance.listen(env.get('PORT')) + process.on('SIGTERM', () => { + logger.info('SIGTERM signal received: closing HTTP server') + serverInstance.close(() => { + logger.info('HTTP server closed') + }) + }) logger.info(`Server started on port ${process.env.PORT}`) }) diff --git a/packages/files/bin/worker.ts b/packages/files/bin/worker.ts index e36dd7af9..4ba1fedb3 100644 --- a/packages/files/bin/worker.ts +++ b/packages/files/bin/worker.ts @@ -22,5 +22,11 @@ void container.load().then((container) => { const subscriber = container.get(TYPES.Files_DomainEventSubscriber) + process.on('SIGTERM', () => { + logger.info('SIGTERM received. Stopping worker...') + subscriber.stop() + logger.info('Worker stopped.') + }) + subscriber.start() }) diff --git a/packages/files/docker/entrypoint.sh b/packages/files/docker/entrypoint.sh index f4c9b15f9..121acc646 100755 --- a/packages/files/docker/entrypoint.sh +++ b/packages/files/docker/entrypoint.sh @@ -6,12 +6,12 @@ COMMAND=$1 && shift 1 case "$COMMAND" in 'start-web' ) echo "Starting Web..." - node docker/entrypoint-server.js + exec node docker/entrypoint-server.js ;; 'start-worker' ) echo "Starting Worker..." - node docker/entrypoint-worker.js + exec node docker/entrypoint-worker.js ;; * ) diff --git a/packages/files/supervisor/supervisor-server.sh b/packages/files/supervisor/supervisor-server.sh index 829d74610..02d33da6f 100755 --- a/packages/files/supervisor/supervisor-server.sh +++ b/packages/files/supervisor/supervisor-server.sh @@ -4,4 +4,4 @@ set -euo pipefail sh supervisor/wait-for.sh $DB_HOST $DB_PORT sh supervisor/wait-for.sh $REDIS_HOST $REDIS_PORT -node docker/entrypoint-server.js +exec node docker/entrypoint-server.js diff --git a/packages/files/supervisor/supervisor-worker.sh b/packages/files/supervisor/supervisor-worker.sh index 71a133808..d09f38d6b 100755 --- a/packages/files/supervisor/supervisor-worker.sh +++ b/packages/files/supervisor/supervisor-worker.sh @@ -3,4 +3,4 @@ set -euo pipefail sh supervisor/wait-for.sh localhost $SYNCING_SERVER_PORT -node docker/entrypoint-worker.js +exec node docker/entrypoint-worker.js diff --git a/packages/home-server/src/Server/HomeServer.ts b/packages/home-server/src/Server/HomeServer.ts index fcb044fcc..8dd4797e7 100644 --- a/packages/home-server/src/Server/HomeServer.ts +++ b/packages/home-server/src/Server/HomeServer.ts @@ -174,7 +174,16 @@ export class HomeServer implements HomeServerInterface { const port = env.get('PORT', true) ? +env.get('PORT', true) : 3000 - this.serverInstance = server.build().listen(port) + const serverInstance = server.build().listen(port) + + this.serverInstance = serverInstance + + process.on('SIGTERM', () => { + logger.info('SIGTERM signal received: closing HTTP server') + serverInstance.close(() => { + logger.info('HTTP server closed') + }) + }) logger.info(`Server started on port ${port}. Log level: ${env.get('LOG_LEVEL', true)}.`) diff --git a/packages/revisions/bin/server.ts b/packages/revisions/bin/server.ts index aae68df3f..3e8acd389 100644 --- a/packages/revisions/bin/server.ts +++ b/packages/revisions/bin/server.ts @@ -43,9 +43,14 @@ void container.load().then((container) => { }) }) - const serverInstance = server.build() + const serverInstance = server.build().listen(env.get('PORT')) - serverInstance.listen(env.get('PORT')) + process.on('SIGTERM', () => { + logger.info('SIGTERM signal received: closing HTTP server') + serverInstance.close(() => { + logger.info('HTTP server closed') + }) + }) logger.info(`Server started on port ${process.env.PORT}`) }) diff --git a/packages/revisions/bin/worker.ts b/packages/revisions/bin/worker.ts index 5016e1ef4..214d058d6 100644 --- a/packages/revisions/bin/worker.ts +++ b/packages/revisions/bin/worker.ts @@ -18,5 +18,11 @@ void container.load().then((container) => { const subscriber = container.get(TYPES.Revisions_DomainEventSubscriber) + process.on('SIGTERM', () => { + logger.info('SIGTERM received. Stopping worker...') + subscriber.stop() + logger.info('Worker stopped.') + }) + subscriber.start() }) diff --git a/packages/revisions/docker/entrypoint.sh b/packages/revisions/docker/entrypoint.sh index f4c9b15f9..121acc646 100755 --- a/packages/revisions/docker/entrypoint.sh +++ b/packages/revisions/docker/entrypoint.sh @@ -6,12 +6,12 @@ COMMAND=$1 && shift 1 case "$COMMAND" in 'start-web' ) echo "Starting Web..." - node docker/entrypoint-server.js + exec node docker/entrypoint-server.js ;; 'start-worker' ) echo "Starting Worker..." - node docker/entrypoint-worker.js + exec node docker/entrypoint-worker.js ;; * ) diff --git a/packages/revisions/supervisor/supervisor-server.sh b/packages/revisions/supervisor/supervisor-server.sh index 7a0b602f9..77f825b23 100755 --- a/packages/revisions/supervisor/supervisor-server.sh +++ b/packages/revisions/supervisor/supervisor-server.sh @@ -3,4 +3,4 @@ set -euo pipefail sh supervisor/wait-for.sh localhost $SYNCING_SERVER_PORT -node docker/entrypoint-server.js +exec node docker/entrypoint-server.js diff --git a/packages/revisions/supervisor/supervisor-worker.sh b/packages/revisions/supervisor/supervisor-worker.sh index 71a133808..d09f38d6b 100755 --- a/packages/revisions/supervisor/supervisor-worker.sh +++ b/packages/revisions/supervisor/supervisor-worker.sh @@ -3,4 +3,4 @@ set -euo pipefail sh supervisor/wait-for.sh localhost $SYNCING_SERVER_PORT -node docker/entrypoint-worker.js +exec node docker/entrypoint-worker.js diff --git a/packages/scheduler/bin/worker.ts b/packages/scheduler/bin/worker.ts index a09406d9b..b814e9d4e 100644 --- a/packages/scheduler/bin/worker.ts +++ b/packages/scheduler/bin/worker.ts @@ -22,5 +22,11 @@ void container.load().then((container) => { const subscriber = container.get(TYPES.DomainEventSubscriber) + process.on('SIGTERM', () => { + logger.info('SIGTERM received. Stopping worker...') + subscriber.stop() + logger.info('Worker stopped.') + }) + subscriber.start() }) diff --git a/packages/scheduler/docker/entrypoint.sh b/packages/scheduler/docker/entrypoint.sh index efe73f810..44aa5c15f 100755 --- a/packages/scheduler/docker/entrypoint.sh +++ b/packages/scheduler/docker/entrypoint.sh @@ -6,12 +6,12 @@ COMMAND=$1 && shift 1 case "$COMMAND" in 'start-worker' ) echo "Starting Worker..." - node docker/entrypoint-worker.js + exec node docker/entrypoint-worker.js ;; 'verify-jobs' ) echo "Starting jobs verification..." - node docker/entrypoint-verify.js + exec node docker/entrypoint-verify.js ;; * ) diff --git a/packages/syncing-server/bin/server.ts b/packages/syncing-server/bin/server.ts index ece34c050..3bd62221a 100644 --- a/packages/syncing-server/bin/server.ts +++ b/packages/syncing-server/bin/server.ts @@ -72,9 +72,14 @@ void container.load().then((container) => { }) }) - const serverInstance = server.build() + const serverInstance = server.build().listen(env.get('PORT')) - serverInstance.listen(env.get('PORT')) + process.on('SIGTERM', () => { + logger.info('SIGTERM signal received: closing HTTP server') + serverInstance.close(() => { + logger.info('HTTP server closed') + }) + }) logger.info(`Server started on port ${process.env.PORT}`) }) diff --git a/packages/syncing-server/bin/worker.ts b/packages/syncing-server/bin/worker.ts index 783022b83..09a6ed168 100644 --- a/packages/syncing-server/bin/worker.ts +++ b/packages/syncing-server/bin/worker.ts @@ -18,5 +18,11 @@ void container.load().then((container) => { const subscriber = container.get(TYPES.Sync_DomainEventSubscriber) + process.on('SIGTERM', () => { + logger.info('SIGTERM received. Stopping worker...') + subscriber.stop() + logger.info('Worker stopped.') + }) + subscriber.start() }) diff --git a/packages/syncing-server/docker/entrypoint.sh b/packages/syncing-server/docker/entrypoint.sh index f8b3184be..31365b616 100755 --- a/packages/syncing-server/docker/entrypoint.sh +++ b/packages/syncing-server/docker/entrypoint.sh @@ -6,12 +6,12 @@ COMMAND=$1 && shift 1 case "$COMMAND" in 'start-web' ) echo "[Docker] Starting Web..." - node docker/entrypoint-server.js + exec node docker/entrypoint-server.js ;; 'start-worker' ) echo "[Docker] Starting Worker..." - node docker/entrypoint-worker.js + exec node docker/entrypoint-worker.js ;; * ) diff --git a/packages/syncing-server/supervisor/supervisor-server.sh b/packages/syncing-server/supervisor/supervisor-server.sh index 829d74610..02d33da6f 100755 --- a/packages/syncing-server/supervisor/supervisor-server.sh +++ b/packages/syncing-server/supervisor/supervisor-server.sh @@ -4,4 +4,4 @@ set -euo pipefail sh supervisor/wait-for.sh $DB_HOST $DB_PORT sh supervisor/wait-for.sh $REDIS_HOST $REDIS_PORT -node docker/entrypoint-server.js +exec node docker/entrypoint-server.js diff --git a/packages/syncing-server/supervisor/supervisor-worker.sh b/packages/syncing-server/supervisor/supervisor-worker.sh index 71a133808..d09f38d6b 100755 --- a/packages/syncing-server/supervisor/supervisor-worker.sh +++ b/packages/syncing-server/supervisor/supervisor-worker.sh @@ -3,4 +3,4 @@ set -euo pipefail sh supervisor/wait-for.sh localhost $SYNCING_SERVER_PORT -node docker/entrypoint-worker.js +exec node docker/entrypoint-worker.js diff --git a/packages/websockets/bin/server.ts b/packages/websockets/bin/server.ts index 7e6cb8c66..dc7a932ff 100644 --- a/packages/websockets/bin/server.ts +++ b/packages/websockets/bin/server.ts @@ -44,9 +44,14 @@ void container.load().then((container) => { }) }) - const serverInstance = server.build() + const serverInstance = server.build().listen(env.get('PORT')) - serverInstance.listen(env.get('PORT')) + process.on('SIGTERM', () => { + logger.info('SIGTERM signal received: closing HTTP server') + serverInstance.close(() => { + logger.info('HTTP server closed') + }) + }) logger.info(`Server started on port ${process.env.PORT}`) }) diff --git a/packages/websockets/bin/worker.ts b/packages/websockets/bin/worker.ts index b3d34fff3..389dcbaf8 100644 --- a/packages/websockets/bin/worker.ts +++ b/packages/websockets/bin/worker.ts @@ -18,5 +18,11 @@ void container.load().then((container) => { const subscriber = container.get(TYPES.DomainEventSubscriber) + process.on('SIGTERM', () => { + logger.info('SIGTERM received. Stopping worker...') + subscriber.stop() + logger.info('Worker stopped.') + }) + subscriber.start() }) diff --git a/packages/websockets/docker/entrypoint.sh b/packages/websockets/docker/entrypoint.sh index f4c9b15f9..121acc646 100755 --- a/packages/websockets/docker/entrypoint.sh +++ b/packages/websockets/docker/entrypoint.sh @@ -6,12 +6,12 @@ COMMAND=$1 && shift 1 case "$COMMAND" in 'start-web' ) echo "Starting Web..." - node docker/entrypoint-server.js + exec node docker/entrypoint-server.js ;; 'start-worker' ) echo "Starting Worker..." - node docker/entrypoint-worker.js + exec node docker/entrypoint-worker.js ;; * )