fix(backend): drain BullMQ workers on graceful shutdown (#1347) - #1396
Open
Kenlachy wants to merge 2 commits into
Open
fix(backend): drain BullMQ workers on graceful shutdown (#1347)#1396Kenlachy wants to merge 2 commits into
Kenlachy wants to merge 2 commits into
Conversation
…o#1347) Kubernetes sends SIGTERM during rolling deploys, but neither the backend nor the oracle called app.enableShutdownHooks(). Without it NestJS never fires onApplicationShutdown, so in-flight webhook deliveries and randomness jobs were killed mid-execution instead of finishing or being returned to the queue. Changes: - Enable app.enableShutdownHooks() in backend/src/main.ts and oracle/src/main.ts - Implement OnApplicationShutdown in WebhookDeliveryWorker (calls worker.close()) - Implement OnApplicationShutdown in RandomnessWorker (calls queue.close()) - Increase terminationGracePeriodSeconds from 30 → 45 in both k8s deployments - Add unit tests verifying shutdown hooks delegate to close() - Add e2e test that SIGTERM during active jobs lets them complete 🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com>
|
@github-actions[bot] is attempting to deploy a commit to the otaiki1's projects Team on Vercel. A member of the Team first needs to authorize it. |
Contributor
|
FIX CONFLICTS |
- webhook-delivery.worker.ts: kept upstream import (InjectQueue) and removed duplicate simpler onApplicationShutdown (kept the more comprehensive one with queue.pause + active job drain) - oracle/src/main.ts: combined enableShutdownHooks (HEAD) with x-request-id correlation middleware (upstream) - oracle/src/queue/randomness.worker.ts: took upstream @optional InjectQueue with randomnessQueue field name, updated onApplicationShutdown to use randomnessQueue?.close() - oracle/k8s/deployment.yaml: accepted upstream deletion (moved to k8s/base/deployment.yaml) 🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com>
Contributor
Author
|
fixed |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Kubernetes sends SIGTERM during rolling deploys, but neither the backend nor the oracle called
app.enableShutdownHooks(). Without it, NestJS never firesonApplicationShutdownon any provider, so in-flight webhook deliveries and randomness jobs are killed mid-execution rather than finishing or being returned to the queue.Solution
Backend (
backend/src/main.ts)app.enableShutdownHooks()beforeapp.listen()so NestJS reacts to SIGTERMBackend worker (
webhook-delivery.worker.ts)OnApplicationShutdown— calls(this as any).worker.close()which tells BullMQ to stop picking up new jobs and wait for in-flight deliveries to finish (or fail) before closing the Redis connectionOracle (
oracle/src/main.ts)app.enableShutdownHooks()beforeapp.listen()Oracle worker (
randomness.worker.ts)OnApplicationShutdown— injects the Bull queue via@InjectQueueand callsthis.queue.close()on shutdown to drain in-flight randomness jobsKubernetes (
k8s/deployment.yaml— both backend & oracle)terminationGracePeriodSecondsfrom 30 → 45 to comfortably exceed the longest job (10s webhook HTTP timeout + retries for backend; on-chain VRF submission time for oracle)Tests
webhook-delivery.worker.spec.tsonApplicationShutdown()callsworker.close(); doesn't throw if worker is undefinedrandomness.worker.spec.tsonApplicationShutdown()callsqueue.close()graceful-shutdown.e2e-spec.tsapp.close(), asserts all in-flight jobs completed before shutdown resolvedHow it works end-to-end
enableShutdownHooks()is enabled)onApplicationShutdown()on every provider that implements itqueue.close()/worker.close()which:terminationGracePeriodSecondsFiles changed
backend/src/main.tsapp.enableShutdownHooks()backend/src/queues/webhook-delivery.worker.tsOnApplicationShutdowninterface + methodbackend/src/queues/webhook-delivery.worker.spec.tsbackend/k8s/deployment.yamlterminationGracePeriodSeconds: 30→45backend/test/graceful-shutdown.e2e-spec.tsoracle/src/main.tsapp.enableShutdownHooks()oracle/src/queue/randomness.worker.tsOnApplicationShutdown+@InjectQueueoracle/src/queue/randomness.worker.spec.tsoracle/k8s/deployment.yamlterminationGracePeriodSeconds: 30→45