Skip to content

Graceful Shutdown Logic Is Duplicated Across All Three Services #254

Description

@therealjhay

Category: Architecture & Refactoring
Difficulty: High

Description:
Graceful shutdown logic is manually implemented in every service:

  • API Gateway: lines 949–968 (inline shutdown function with fastify.close() + prisma.$disconnect())
  • FX Engine: lines 467–497 (inline shutdown function with fastify.close() + redis.quit())
  • Settlement Engine: lines 638–702 (comprehensive shutdown with timeout, worker.close(), queue.close(), redis.quit(), prisma.$disconnect())
  • Indexer: lines 547–553 (inline SIGTERM handler with prisma.$disconnect(), webhookQueue.close(), webhookWorker.close(), fastify.close())

Each implementation has subtle differences: the settlement engine has a 30-second force-exit timeout, the indexer doesn't, the gateway doesn't close Redis or BullMQ resources. This duplication means bug fixes to shutdown handling must be applied in 4 places. A shared gracefulShutdown(fastify, options) function should be extracted.

Location:
services/api-gateway/src/index.ts:949–968, services/fx-engine/src/index.ts:467–497, services/settlement-engine/src/index.ts:638–702, services/indexer/src/index.ts:547–553

Acceptance Criteria:

  • Extract a gracefulShutdown function into @bettapay/validation/shutdown.ts
  • The function should accept an options object: { fastify, prisma?, redis?, bullmq?: { worker?, queues? } }
  • Enforce a configurable force-exit timeout (default 30s) matching the settlement engine's pattern
  • Replace all 4 inline shutdown implementations with the shared function
  • Write tests verifying the shutdown sequence (mock close methods, verify order)
  • Ensure process.exit(0) is called after successful shutdown, process.exit(1) on failure

Technical Notes:

  • Resource close order: server → accept new connections (fastify.close) → workers → queues → redis → prisma.
  • Use Promise.allSettled to ensure all resources attempt close even if one fails.

Metadata

Metadata

Labels

GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial Campaign | FWC26Campaign: Official Campaign | FWC26

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions