fix(mcp): multi-agent session, resource routing, and bridge parity#86
fix(mcp): multi-agent session, resource routing, and bridge parity#86khaliqgant merged 5 commits intomainfrom
Conversation
|
Preview deployed!
This preview shares the staging database and will be cleaned up when the PR is merged or closed. Run E2E testsnpm run e2e -- https://pr86-api.relaycast.dev --ciOpen observer dashboard |
|
Basically allows sub agents to communicate independently via relaycast |
| try { | ||
| const timeout = new Promise<never>((_, reject) => | ||
| setTimeout(() => reject(new Error(`Bootstrap timed out after ${timeoutMs}ms`)), timeoutMs), | ||
| ); | ||
| return await Promise.race([doBootstrap(), timeout]); |
There was a problem hiding this comment.
🟡 Timer leak in bootstrapOneWorkspace prevents clean event loop drain
When doBootstrap() resolves before the timeout, the setTimeout timer created for the timeout promise at packages/mcp/src/transports.ts:72-74 is never cleared. The timer remains active, holding a ref on the Node.js event loop for up to timeoutMs (default 5 seconds). Since bootstrapWorkspaces runs all workspaces concurrently via Promise.allSettled (packages/mcp/src/transports.ts:96-98), up to N lingering timers can accumulate. When the timers eventually fire, they call reject() on an already-settled promise (a no-op), but until that point they prevent graceful process shutdown and consume memory for the timer reference and its closure.
| try { | |
| const timeout = new Promise<never>((_, reject) => | |
| setTimeout(() => reject(new Error(`Bootstrap timed out after ${timeoutMs}ms`)), timeoutMs), | |
| ); | |
| return await Promise.race([doBootstrap(), timeout]); | |
| try { | |
| let timer: ReturnType<typeof setTimeout>; | |
| const timeout = new Promise<never>((_, reject) => { | |
| timer = setTimeout(() => reject(new Error(`Bootstrap timed out after ${timeoutMs}ms`)), timeoutMs); | |
| }); | |
| const result = await Promise.race([doBootstrap(), timeout]); | |
| clearTimeout(timer!); | |
| return result; |
Was this helpful? React with 👍 or 👎 to provide feedback.
When doBootstrap() resolves before the timeout, the setTimeout timer was never cleared, holding a ref on the event loop and preventing clean shutdown. Now clears the timer on success. Addresses Devin review on PR #86.
Summary
asoverrides for resources and piggyback, without changing legacy resource URIs.relay://URIs to preserve MCP compatibility.as.Verification