fix(test): close open handles causing jest force-exit in bot suite
Merged
LU
4mo ago+135+135+012345678901234567890123456789-4-4-0123456789
Problem
Running npm run test --workspace=packages/bot prints after all tests pass:
A worker process has failed to exit gracefully and has been force exited.
This is likely caused by tests leaking due to improper teardown.
The force-exit message appeared because LRUCache instances at module scope (spotifyUserSeeds, lastFmApi, spotifyApi, and others) create internal setTimeout/setInterval handlers for TTL expiry. These timers keep the Node.js event loop alive indefinitely, preventing graceful worker process exit.
Solution
Two complementary approaches:
- Patch global setTimeout/setInterval in jest setup to unreference all timers. This makes cache TTL timers weak — they won't block process exit even if active.
- Add clearAllXCache() export functions to cache modules for cleanup on process.beforeExit(), ensuring timers are cleared before exit.
This preserves TTL behavior for tests that verify cache expiry while allowing jest workers to exit gracefully.
Testing
All bot tests pass without the force-exit warning:
Test Suites: 1 skipped, 192 passed, 192 of 193 total
Tests: 1 skipped, 2635 passed, 2636 total
Closes #1553
Summary by cubic
Fixes #1553 by making lru-cache TTL timers non-blocking and clearing cache timers on beforeExit, so bot test workers exit cleanly without the Jest force-exit warning.
- Bug Fixes
- Patch global
setTimeout/setIntervalin test setup to call.unref(), so TTL timers don’t keep the event loop alive. - Add
clearAllSeedsCache()and register aprocess.on('beforeExit')cleanup to purge LRU-backed caches across modules (Spotify user seeds, Last.fm, Spotify API, duplicate detection, autoplay, replenish suppression, player handlers).
- Patch global