Repository navigation
fix(microvm-worker): suspend once, answer resends during a refusal - #842
Merged
ParidelPooya merged 7 commits intoOct 26, 2026
Merged
Conversation
A SuspendMicrovm retry can run after the MicroVM resumed and freeze the next job. The default client now makes one attempt, and the before-send handler starts no attempt after a resume hook.
A resend of a known job got 503 while the worker refused jobs. The durable function then resumed the MicroVM only to get the duplicate answer. The worker now answers a known callback ID with 202 first.
The 503 note for a resent job said that nothing would suspend the MicroVM again. The idle time restarts after the refusal, so the worker does suspend it again. The real cost is a resume of the MicroVM for nothing. A resume hook can stop the first SuspendMicrovm attempt. Nothing was sent then. The classification docs now say that an earlier attempt, if there was one, may have suspended the MicroVM. The README now states the cost of one attempt. A first-attempt 5xx or dropped connection counts as unknown, and the worker refuses jobs for up to 30 seconds on a MicroVM that did not suspend. It also states why a resent job whose callback is gone gets 202 after the terminate hook.
The JavaScript worker logs an info line when a resume hook arrives during its SuspendMicrovm call. This worker logged nothing until the unknown warning at the end of the call. It now logs the same line, with the same text and the call's microvmId. The resume hook decides under the lock and logs after it. Only the first resume hook during a call logs the line. A resume hook after the call returned logs nothing, because no attempt is left to stop. New listener tests cover a resume hook before the first attempt, a suspend hook after that resume and before the call returns, a second resume hook during the call, and a resume hook after the call returned. The README documents the line. It also states that the JavaScript worker cancels the attempt in flight, while this worker can only stop the next attempt.
…spend-retry-and-duplicates
yaythomas
reviewed
Oct 26, 2026
A resend of a running job during a suspend refusal got HTTP 202. The running job can freeze with the MicroVM. send_job treats 202 as success, so it did not check the state again and did not resume the MicroVM. The job then waited for its heartbeat timeout or its timeout. Such a resend now gets HTTP 503, as a new job does, and starts nothing. The 503 makes the durable function check the state, resume the MicroVM, and deliver the job again. A finished job still gets 202 in every state. A known job still gets 202 after the terminate hook. A composed test with the request step covers the sequence: a lost 202, a recheck that sees RUNNING, a suspend hook, and the resend.
ParidelPooya
marked this pull request as ready for review
October 26, 2026 04:36
ParidelPooya
added a commit
to aws/aws-durable-execution-sdk-js
that referenced
this pull request
Oct 26, 2026
…1100) ## Summary This PR fixes two defects in the MicroVM worker's auto-suspend. A retried `SuspendMicrovm` could suspend the MicroVM during the next job. A second delivery of a known job got HTTP 503 while the worker refused jobs. ## Why 1. The worker's own `SuspendMicrovm` client made up to 3 attempts. 2. An attempt can suspend the MicroVM and lose its answer in the freeze. 3. The durable function then resumes the MicroVM. The `resume` hook ends the worker's refusal, and the next job starts. 4. The client then retried. The retry suspended the MicroVM with the job inside. Nothing resumed it, so the job failed at its heartbeat timeout or its timeout. 5. A live test showed that `SuspendMicrovm` succeeds on a MicroVM that is already suspending or suspended. So a retry gains nothing, and one attempt is enough. The second defect: 1. The durable function sends a job again when it lost the first 202, or when its request step runs again on replay. 2. The worker answered such a delivery with HTTP 503 while it refused jobs for a suspend or a `terminate` hook. 3. After the 503, the durable function resumed the MicroVM, sent the job again, and got 202. So the MicroVM ran again for nothing. Both defects come before the planned `suspendAfter` option on `vm.invoke`, which uses the same suspend path. The Python SDK fixes the same defects in aws/aws-durable-execution-sdk-python#842. ## Changes - The worker's own `lambda-microvms` client uses `maxAttempts: 1`. - The call's signal combines the 10-second deadline with an abort controller. The `resume` hook aborts a call that still runs. So a client from `createMicrovmsClient` that retries sends no later attempt either. - An aborted call counts as an unknown outcome. The `resume` hook has already ended the refusal, so the worker starts no new one. - With one attempt, a throttle or a clock-skew error from the worker's own client now counts as refused for now. So the worker accepts jobs again at once, and tries the call again after at least 30 seconds. Before, the retried error counted as unknown, and the worker refused jobs for up to 30 seconds. - The job handler checks for a known callback ID before the suspend and `terminate` refusals. A second delivery of a finished job gets HTTP 202 in every state. A second delivery of a running job gets HTTP 202, except during a suspend refusal. There it gets HTTP 503, because the running job may freeze, and the 503 makes the durable function check the state and resume the MicroVM. A new job still gets HTTP 503 during the refusal. The `run` hook already checked for a known job first. - README "Auto-suspend" and "Suspend and terminate hooks", and CHANGELOG, are updated. ## Testing - New tests: the worker's own client makes one attempt; the `resume` hook aborts a running call, so a client that retries sends no later attempt; the idle time starts when the aborted call ends; a second delivery of a running or finished job gets 202 during a refusal and after the `terminate` hook, and starts nothing; a second `resume` hook during the call aborts once; a `suspend` hook after the abort keeps its refusal. a resend of a running job gets 503 during a suspend refusal, and a composed test with the extras request step resumes the MicroVM in that case. The first 7 tests fail on `main`. - Worker `npm test`: 305 tests pass, with coverage of 96.81% statements and 92.78% branches. `npm run lint` and `npm run format:check` pass. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
ParidelPooya
deleted the
fix/microvm-worker-suspend-retry-and-duplicates
branch
October 26, 2026 04:39
Contributor
Codex AI reviewNo actionable findings in the PR changes. Tests were inspected but not executed under the review constraints; live MicroVM freeze/resume timing remains unverified by this review. Reviewed commit |
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR fixes two defects in the MicroVM worker's auto-suspend. A retried
SuspendMicrovmcould suspend the MicroVM during the next job. A second delivery of a known job got HTTP 503 while the worker refused jobs.Why
lambda-microvmsclient made up to 3 attempts.resumehook ends the worker's refusal, and the next job starts.SuspendMicrovmsucceeds on a MicroVM that is already suspending or suspended. So a retry gains nothing, and one attempt is enough.The second defect:
terminatehook.Both defects come before the planned
suspend_afteroption onvm.invoke, which uses the same suspend path. The JavaScript SDK fixes the same defects in aws/aws-durable-execution-sdk-js#1100.Changes
create_microvms_clientusestotal_max_attemptsof 1.suspend_microvmtakes aresumedcallable. Thebefore-sendhandler raisesSuspendResumedErrorwhen it returnsTrue. So a client fromcreate_microvms_clientthat retries starts no attempt after aresumehook. botocore cannot cancel an attempt in flight, so an attempt that started before the hook still runs to its end.resumehooks, and passes the count at the call's start to the handler.SuspendResumedErrorcounts as an unknown outcome. Theresumehook has already ended the refusal, so the worker starts no new one.resumehook during the call logsstopping the suspend call: the MicroVM resumed during it, as the JavaScript worker does.terminaterefusals. A second delivery of a finished job gets HTTP 202 in every state. A second delivery of a running job gets HTTP 202, except during a suspend refusal. There it gets HTTP 503, because the running job may freeze, and the 503 makes the durable function check the state and resume the MicroVM. A new job still gets HTTP 503 during the refusal. Therunhook already checked for a known job first.Testing
resumehook, also before the first attempt, and starts the attempt while no hook arrived; the worker sends no attempt after theresumehook; a second delivery of a running or finished job gets 202 during a suspend refusal and after theterminatehook; aresumehook while the client is created stops the first attempt; asuspendhook after a stopped call keeps its refusal; a secondresumehook logs the stop line once; a resend of a running job gets 503 during a suspend refusal, and a composed test with the extras request step resumes the MicroVM in that case.hatch run dev-microvm-worker:cov: 473 tests pass, with 100% coverage ofworker.pyandself_suspend.py.typecheck,hatch fmt --check, andlintcommit.pypass.By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.