Skip to content

feat(quotas): add graceful shutdown drain for /api/quotas - #1042

Merged
greatest0fallt1me merged 1 commit into
CalloraOrg:mainfrom
mrteeednut007-dotcom:feat/quotas-graceful-shutdown
Jul 29, 2026
Merged

feat(quotas): add graceful shutdown drain for /api/quotas#1042
greatest0fallt1me merged 1 commit into
CalloraOrg:mainfrom
mrteeednut007-dotcom:feat/quotas-graceful-shutdown

Conversation

@mrteeednut007-dotcom

Copy link
Copy Markdown
Contributor

Closes #883

Summary

Implements a SIGTERM-safe drain for in-flight /api/quotas requests so the process never closes database connections while quota count queries are still executing.

What changed

File Change
src/routes/quotas/counts.ts Creates quotasDrainTracker via createInFlightDrainTracker("quotas"), applies its middleware to the router
src/app.ts Re-exports quotasDrainTracker so entry-points can import it without reaching into the route module
src/index.ts Registers quotasDrainTracker.subsystem in the shutdownSubsystems array passed to createGracefulShutdownHandler
src/routes/quotas/counts.test.ts 14 focused tests (new file)

How it works

On SIGTERM / SIGINT the existing createGracefulShutdownHandler iterates shutdownSubsystems and calls beginShutdown() + awaitIdle() on each. Adding quotasDrainTracker.subsystem to that list means:

  1. beginShutdown() — the tracker stops accepting new work and sets Connection: close on responses so clients reconnect after restart.
  2. awaitIdle() — the shutdown handler waits until the in-flight counter reaches zero before proceeding to close the database pool.

Testing

Tests:    14 passed
Coverage on counts.ts:
  Statements: 92.85% | Functions: 100% | Lines: 92.85%

Lint passes on all changed files. Pre-existing warnings in src/index.ts (createRateLimiter, createSettlementReconciliationJob unused) are unchanged from main.

Closes CalloraOrg#883

Implements a SIGTERM-safe drain for in-flight /api/quotas requests so
the process never closes database connections while quota count queries
are still executing.

Changes:
- src/routes/quotas/counts.ts
    Creates a module-level createInFlightDrainTracker("quotas") instance
    (quotasDrainTracker) and applies its middleware to the router.  During
    shutdown the middleware sets Connection: close on new responses so
    clients reconnect after the process restarts.

- src/app.ts
    Re-exports quotasDrainTracker from counts.ts so application
    entry-points can import it without reaching into the route module.

- src/index.ts
    Imports quotasDrainTracker and registers its subsystem in the
    shutdownSubsystems array passed to createGracefulShutdownHandler.
    The shutdown sequence now drains /api/quotas alongside the existing
    gateway-proxy, api-keys, and webhook-dispatcher subsystems.

- src/routes/quotas/counts.test.ts  (new)
    14 focused tests covering:
    * quotasDrainTracker shape (middleware + subsystem exported)
    * subsystem.name = "quotas"
    * awaitIdle resolves immediately when idle
    * awaitIdle waits for in-flight request to complete (drain path)
    * beginShutdown sets Connection: close on subsequent responses
    * middleware is transparent for normal 200 responses
    * GET /api/quotas/counts happy-path counts (total/pending/approved/rejected)
    * 401 without auth
    * Cross-user isolation
    * Correlation ID echo
    * Error propagation to errorHandler

Coverage on counts.ts: 92.85% stmts | 100% funcs | 100% branches tested
@drips-wave

drips-wave Bot commented Jul 29, 2026

Copy link
Copy Markdown

@mrteeednut007-dotcom Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@mrteeednut007-dotcom

Copy link
Copy Markdown
Contributor Author

feat(quotas): add graceful shutdown drain for /api/quotas

Closes #883

Summary

Implements a SIGTERM-safe drain for in-flight /api/quotas requests so the process never closes
database connections while quota count queries are still executing.

What changed

┌─────────────────────────────┬─────────────────────────────────────────────────────────────┐
│ File │ Change │
├─────────────────────────────┼─────────────────────────────────────────────────────────────┤
│ src/routes/quotas/counts.ts │ Creates quotasDrainTracker via │
│ │ createInFlightDrainTracker("quotas"), applies its │
│ │ middleware to the router │
├──────────────────────────────────┼────────────────────────────────────────────────────────┤
│ src/app.ts │ Re-exports quotasDrainTracker so entry-points can │
│ │ import it without reaching into the route module │
├──────────────────────────────────┼────────────────────────────────────────────────────────┤
│ src/index.ts │ Registers quotasDrainTracker.subsystem in the │
│ │ shutdownSubsystems array passed to │
│ │ createGracefulShutdownHandler │
├──────────────────────────────────┼────────────────────────────────────────────────────────┤
│ src/routes/quotas/counts.test.ts │ 14 focused tests (new file) │
└──────────────────────────────────┴────────────────────────────────────────────────────────┘

How it works

On SIGTERM / SIGINT the existing createGracefulShutdownHandler iterates shutdownSubsystems and
calls beginShutdown() + awaitIdle() on each. Adding quotasDrainTracker.subsystem to that list
means:

  1. beginShutdown() — the tracker marks the subsystem as draining and sets Connection: close on
    responses so clients reconnect after restart.
  2. awaitIdle() — the shutdown handler waits until the in-flight request counter reaches zero
    before proceeding to close the database pool.

No new dependencies. No changes to the public API shape.

Testing

Tests: 14 passed
Coverage on counts.ts:
Statements: 92.85% | Functions: 100% | Lines: 92.85%

Covers:

  • quotasDrainTracker shape (middleware + subsystem exported, name = "quotas")
  • awaitIdle resolves immediately when idle
  • awaitIdle waits for in-flight request to complete (drain path)
  • beginShutdown sets Connection: close on subsequent responses
  • Middleware is transparent for normal 200 responses
  • GET /api/quotas/counts happy-path counts (total / pending / approved / rejected)
  • 401 without auth, cross-user isolation, correlation ID echo, error propagation

Lint passes on all changed files. Pre-existing warnings in src/index.ts (createRateLimiter,
createSettlementReconciliationJob unused) are unchanged from main.
closes #890
closes #883

@greatest0fallt1me
greatest0fallt1me merged commit 88666c2 into CalloraOrg:main Jul 29, 2026
1 check passed
@greatest0fallt1me

Copy link
Copy Markdown
Contributor

LGTM ✅ green CI, clean work — merging!

@mrteeednut007-dotcom

Copy link
Copy Markdown
Contributor Author

feat(quotas): add graceful shutdown drain for /api/quotas

Closes #890

Summary

Implements a SIGTERM-safe drain for in-flight /api/quotas requests so the process never closes
database connections while quota count queries are still executing.

What changed

┌─────────────────────────────┬─────────────────────────────────────────────────────────────┐
│ File │ Change │
├─────────────────────────────┼─────────────────────────────────────────────────────────────┤
│ src/routes/quotas/counts.ts │ Creates quotasDrainTracker via │
│ │ createInFlightDrainTracker("quotas"), applies its │
│ │ middleware to the router │
├──────────────────────────────────┼────────────────────────────────────────────────────────┤
│ src/app.ts │ Re-exports quotasDrainTracker so entry-points can │
│ │ import it without reaching into the route module │
├──────────────────────────────────┼────────────────────────────────────────────────────────┤
│ src/index.ts │ Registers quotasDrainTracker.subsystem in the │
│ │ shutdownSubsystems array passed to │
│ │ createGracefulShutdownHandler │
├──────────────────────────────────┼────────────────────────────────────────────────────────┤
│ src/routes/quotas/counts.test.ts │ 14 focused tests (new file) │
└──────────────────────────────────┴────────────────────────────────────────────────────────┘

How it works

On SIGTERM / SIGINT the existing createGracefulShutdownHandler iterates shutdownSubsystems and
calls beginShutdown() + awaitIdle() on each. Adding quotasDrainTracker.subsystem to that list
means:

  1. beginShutdown() — the tracker marks the subsystem as draining and sets Connection: close on
    responses so clients reconnect after restart.
  2. awaitIdle() — the shutdown handler waits until the in-flight request counter reaches zero
    before proceeding to close the database pool.

No new dependencies. No changes to the public API shape.

Testing

Tests: 14 passed
Coverage on counts.ts:
Statements: 92.85% | Functions: 100% | Lines: 92.85%

Covers:

  • quotasDrainTracker shape (middleware + subsystem exported, name = "quotas")
  • awaitIdle resolves immediately when idle
  • awaitIdle waits for in-flight request to complete (drain path)
  • beginShutdown sets Connection: close on subsequent responses
  • Middleware is transparent for normal 200 responses
  • GET /api/quotas/counts happy-path counts (total / pending / approved / rejected)
  • 401 without auth, cross-user isolation, correlation ID echo, error propagation

Lint passes on all changed files. Pre-existing warnings in src/index.ts (createRateLimiter,
createSettlementReconciliationJob unused) are unchanged from main.

closes #890

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add graceful shutdown drain for /api/quotas [b#018]

2 participants