fix: close shared http.Agent on worker graceful shutdown (#225)#268
Merged
Xhristin3 merged 4 commits intoJun 16, 2026
Conversation
…z#225) The shutdown hook was creating a brand-new Agent() and calling destroy() on it — a no-op for the actual axios HTTP keep-alive pool. Fix: - Create a shared http.Agent({ keepAlive: true }) at module level - Pass it to axios.create({ httpAgent }) so all requests reuse the pool - Call httpAgent.destroy() in shutdown() to close all sockets on exit Also: - Export httpAgent and shutdown for testability - Add __tests__/worker.test.ts covering: Agent type/keepAlive, axios wiring, destroy called on shutdown, process.exit(0), idempotency - Add forceExit: true to jest config (background poll loop holds event loop)
- Rename GracefulShutdown instance to gracefulShutdown to avoid naming
conflict with the exported shutdown function
- Replace new Agent().destroy() with httpAgent.destroy() in the
'close http pool' hook — the previous code created a throwaway agent
and destroyed it, which was a no-op for the actual connection pool
- Export shutdown as a testable async function wrapper around
gracefulShutdown.requestShutdown()
- Remove duplicate 'import { Agent } from http' (http already imported)
Contributor
Author
|
PR submitted for review and merging |
Xhristin3
approved these changes
Jun 16, 2026
Xhristin3
left a comment
Contributor
There was a problem hiding this comment.
Solid fix @olaleyeolajide81-sketch! You nailed it — shared http.Agent({ keepAlive: true }) at module level, wired through axios.create({ httpAgent }), and destroyed on shutdown. Tests cover agent type, keepAlive flag, axios wiring, destroy-on-shutdown, process.exit(0), and idempotency. The naming conflict fix (gracefulShutdown vs shutdown export) was a nice catch too. Closes #225 perfectly. 🎯
3 tasks
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
The shutdown hook in
xstreamroll-processing/src/worker.tswas creating a brand-newAgent()and callingdestroy()on it — a no-op for the actual axios HTTP keep-alive pool. HTTP connections were never properly closed on shutdown, leading to connection leaks.Fix
http.Agent({ keepAlive: true })at module level (httpAgent)axios.create({ httpAgent })so all HTTP requests use the same poolhttpAgent.destroy()insideshutdown()to close all pooled sockets on graceful exitChanges
xstreamroll-processing/src/worker.ts— shared agent, axios instance, destroy on shutdown;httpAgentandshutdownexported for testabilityxstreamroll-processing/__tests__/worker.test.ts— new test suite (5 tests): Agent is a keep-alivehttp.Agent,axios.createreceives the shared agent,destroy()is called on shutdown,process.exit(0)is called, shutdown is idempotentxstreamroll-processing/package.json— addedforceExit: trueto jest configTests
All 18 tests pass (3 suites, exit code 0):
Closes #225