Repository navigation
fix(isolated-vm): drain worker host deploys without failing in-flight executions - #9389
Conversation
… executions - Retire each remote worker connection at a max age (IVM_REMOTE_WORKER_MAX_AGE_MS, default 2 min) so a host the load balancer deregistered stops getting new executions and drains before its deregistration delay cuts the connections - Re-dispatch an execution whose connection closed before it was sent; one that may have reached the host is never re-run and fails with a clear error - Cap raw bytes a host connection may send before authenticating (16 KiB) - Return a cancelled call before reading the worker-target flag
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
There was a problem hiding this comment.
All reported issues were addressed across 6 files
This PR changes concurrency-sensitive code such as locks, queues, or retries. Ultrareviews find 2.4x more serious bugs than standard reviews. Comment @cubic-dev-ai ultrareview to run one.
Turn on auto-fix | Re-trigger cubic
[Medium impact] The PR appears safe to merge; no blocking findings remain. SummaryRemote workers stop taking new work when their connections reach the age limit, finish active executions, then close.
|
- Keep counting a refused connection's bytes until its socket closes - Skip a redispatch the caller cancelled in between - Look up the owner's state after the admission waits - Parse IVM_REMOTE_WORKER_MAX_AGE_MS strictly, falling back below 1s - Hold the inspected execution open until the worker check finishes
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
|
@greptile review |
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
Summary
IVM_REMOTE_WORKER_MAX_AGE_MS, default 2 min, jittered down by up to 20%): it takes no new work, finishes what it runs, then closes. New connections land on a healthy host, and the old host's connections age out before its deregistration delay, which infra sizes as max age + the longest execution a release keeps alive + margin (companion infra PR)maxPayloadframe on each pending connectionexecuteInIsolatedVMreturns an already-cancelled or misconfigured call before reading the worker-target flag, instead of waiting on that read firstType of Change
Testing
scripts/test-isolated-vm-remote-e2e.ts(real hosts over real WebSockets) now routes the app through a TCP balancer that behaves like the internal ALB. New check: executions start, the balancer stops routing new connections to the host while keeping open ones, new executions keep arriving until the delay is nearly over, then the balancer cuts what is left and the host gets SIGTERM. Every execution must succeed, nothing may still be open on the old host at expiry, and work must move to the replacement. On the pre-fix sources it fails with 6 of 20 executions reporting "Code execution failed unexpectedly"; with the fix all 19 checks passlib/execution/isolated-vm.test.ts: a pre-aborted call with a never-resolving flag read returnscancelled(hangs before the fix), and an execution dispatched onto a closing connection completes on a new worker (timed out before the fix). Both reverted-guard runs went redcheck:comment-hygiene,check:utils,check:test-patterns,check:explicit-any,check:source-conventions,check:unused-exports; CI runs the restChecklist
test-auditauthoring gate)