Uh oh!
There was an error while loading. Please reload this page.
Fork/feat/swap pgboss for graphile worker - #474
Conversation
|
@arielweinberger is attempting to deploy a commit to the Vercel Labs Team on Vercel. A member of the Team first needs to authorize it. |
| if (runner) { | ||
| await runner.stop(); | ||
| runner = null; | ||
| } | ||
| if (workerUtils) { | ||
| await workerUtils.release(); | ||
| workerUtils = null; |
There was a problem hiding this comment.
| if(runner){ | |
| awaitrunner.stop(); | |
| runner=null; | |
| } | |
| if(workerUtils){ | |
| awaitworkerUtils.release(); | |
| workerUtils=null; | |
| try{ | |
| if(runner){ | |
| awaitrunner.stop(); | |
| runner=null; | |
| } | |
| }finally{ | |
| if(workerUtils){ | |
| awaitworkerUtils.release(); | |
| workerUtils=null; | |
| } |
The stop() method has a resource leak: if runner.stop() throws an exception, the workerUtils.release() cleanup code will never execute, leaving database connections open.
View Details
Analysis
Resource leak in queue.stop() when runner.stop() throws
What fails: The stop() method in packages/world-postgres/src/queue.ts (lines 170-179) does not guarantee workerUtils.release() cleanup if runner.stop() throws an exception. If an exception occurs during runner.stop(), workerUtils.release() never executes, leaving database connections open indefinitely.
How to reproduce: Any exception thrown by runner.stop() (e.g., "Runner is already stopped" if called on an already-stopped instance, or network errors during graceful shutdown) will skip the workerUtils.release() call.
// Current code - if runner.stop() throws, cleanup is skippedasyncstop(){if(runner){awaitrunner.stop();// If this throws, next line doesn't executerunner=null;}if(workerUtils){awaitworkerUtils.release();// Unreachable if runner.stop() throwsworkerUtils=null;}}Result: Database connections managed by workerUtils remain open, causing a resource leak.
Expected:workerUtils.release() should execute regardless of whether runner.stop() succeeds or fails. Per graphile-worker documentation, release() is critical for cleaning up database connections, LISTEN/NOTIFY listeners, signal handlers, and job batch operations.
Fix: Use try-finally to ensure cleanup always occurs:
asyncstop(){try{if(runner){awaitrunner.stop();runner=null;}}finally{if(workerUtils){awaitworkerUtils.release();workerUtils=null;}}}
No description provided.