fix(dev): stop max listeners exceeded warning messages when running more than 10 runs concurrently (#2771)

<!-- CURSOR_SUMMARY -->
> [!NOTE]
> Centralizes SIGTERM handling in `DevSupervisor` and removes per-run
SIGTERM listeners in `DevRunController` to avoid
MaxListenersExceededWarning under high concurrency.
> 
> - **Dev runtime**:
> - **SIGTERM handling**: Add centralized handler in
`packages/cli-v3/src/dev/devSupervisor.ts` to gracefully stop all run
controllers; unregisters on `shutdown()`.
> - **Cleanup**: Remove per-controller `SIGTERM` listener and handler
from `packages/cli-v3/src/entryPoints/dev-run-controller.ts` to reduce
event listeners and warnings.
> - **Changeset**: Add patch note in
`.changeset/fuzzy-ghosts-admire.md`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
5ad2f5341829cebf6fd37a3c616a2db5e4ad936a. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
This commit is contained in:
Eric Allam
2025-12-09 09:54:28 +00:00
committed by GitHub
parent f62cdfe00e
commit c021d1db63
3 changed files with 20 additions and 8 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"trigger.dev": patch
---
fix(dev): stop max listeners exceeded warning messages when running more than 10 runs concurrently
+15
View File
@@ -138,11 +138,26 @@ class DevSupervisor implements WorkerRuntime {
//start an SSE connection for presence
this.disconnectPresence = await this.#startPresenceConnection();
// Handle SIGTERM to gracefully stop all run controllers
process.on("SIGTERM", this.#handleSigterm);
//start dequeuing
await this.#dequeueRuns();
}
#handleSigterm = async () => {
logger.debug("[DevSupervisor] Received SIGTERM, stopping all run controllers");
const stopPromises = Array.from(this.runControllers.values()).map((controller) =>
controller.stop()
);
await Promise.allSettled(stopPromises);
};
async shutdown(): Promise<void> {
process.off("SIGTERM", this.#handleSigterm);
this.disconnectPresence?.();
try {
this.socket?.close();
@@ -122,14 +122,8 @@ export class DevRunController {
logger.debug("[DevRunController] Failed to poll for snapshot", { error });
},
});
process.on("SIGTERM", this.sigterm.bind(this));
}
private async sigterm() {
logger.debug("[DevRunController] Received SIGTERM, stopping worker");
await this.stop();
}
// This should only be used when we're already executing a run. Attempt number changes are not allowed.
private updateRunPhase(run: Run, snapshot: Snapshot) {
@@ -856,8 +850,6 @@ export class DevRunController {
async stop() {
logger.debug("[DevRunController] Shutting down");
process.off("SIGTERM", this.sigterm);
if (this.taskRunProcess && !this.taskRunProcess.isBeingKilled) {
try {
const version = this.opts.worker.serverWorker?.version || "unknown";