Repository navigation
feat(extras): reject an oversized MicroVM input - #833
Conversation
The worker accepts a job body of at most 6 MiB. So microvm and vm.invoke now measure the input's JSON before any durable operation starts. An input over 6 MiB minus 8 KiB raises ValueError.
The extras now reject an input that does not fit before they send it. So the worker answers an oversized body with a plain 400 and closes the connection. It no longer reads and drops the body or handles Expect.
This addresses the review. The bound now uses the API model limits of the MicroVM ID and the callback ID, so the fields take less than 3 KiB.
This addresses the review. The JS and the Python extras packages both reject a job input that does not fit in the worker's body limit.
…size-check # Conflicts: # packages/aws-durable-execution-sdk-python-extras/README.md # packages/aws-durable-execution-sdk-python-extras/src/aws_durable_execution_sdk_python_extras/microvm/operation.py # packages/aws-durable-execution-sdk-python-extras/src/aws_durable_execution_sdk_python_extras/microvm/session.py
|
This change assumes that every supported SDK rejects an oversized input before sending it. JS #1088 does not yet guarantee that. It validates the input as a root JSON value but sends it as a nested value. A key-sensitive |
|
Recorded aws/aws-durable-execution-sdk-js#1088 as a merge dependency in the description. #1088 now measures the nested form (90122f96) and covers the key-sensitive |
## Summary `microvm` and `vm.invoke` reject a job input whose JSON is over 6 MiB minus 8 KiB, with a `RangeError`, before any durable operation starts. ## Why 1. The worker refuses a job body over 6 MiB. 2. The request step did not check the size. 3. So an oversized job launched a MicroVM first. The worker then answered 400, or reset the connection. 4. The request step retries a reset in both retry tiers, for minutes, while the MicroVM is billed. 5. So the operation now checks the size at the call. This is item D5 of a review of the MicroVM safeguards. The Python SDK gets the same rule and message in aws/aws-durable-execution-sdk-python#833. ## Changes - `MAX_JOB_INPUT_BYTES` is 6 MiB minus 8 KiB, exported next to the other limits. The body also holds the version, the Region, the MicroVM ID, the callback ID and the heartbeat timeout. Those fields take less than 3 KiB. - `validateJobInput` measures `Buffer.byteLength(JSON.stringify(input))`, as the body encodes the input. - The message: `MicroVM "<name>": the job input is <n> bytes as JSON. The limit is <limit> bytes, because the worker accepts a job body of at most 6 MiB. Pass larger data by reference, for example as an S3 key.` - A value that `JSON.stringify` cannot encode, such as a `BigInt`, now also fails before any durable operation. The `TypeError` says `MicroVM "<name>": the job input must be JSON-serializable: <detail>`, as in Python, with the `JSON.stringify` error as its `cause`. - An execution that started on an earlier build, with an input in the last 8 KiB below the old limit, fails at its next replay. The CHANGELOG says so. - README "Defaults and limits", "Errors" and Best practices "Job inputs" are updated. CHANGELOG has a `Changed` entry. ## Testing - 14 new tests run "x", "é" (2 bytes) and "😀" (4 bytes) through `microvm` and `vm.invoke`. The largest input that fits is delivered, and its body stays within 6 MiB. One character more is rejected with the exact message, with no durable operation, no `RunMicrovm` call and no request. A `BigInt` input fails before any durable operation. - Extras `npm test`: 347 tests pass. `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.
Merge dependency: merge aws/aws-durable-execution-sdk-js#1088 first. This PR removes the worker's handling of an oversized body, so every SDK must reject an oversized input before it sends it.
Summary
microvmandvm.invokereject a job input whose JSON is over 6 MiB minus 8 KiB, with aValueError, before any durable operation starts. The worker then no longer needs to read and drop an oversized body, so that code is removed.Why
Expect: 100-continueand read and dropped up to 24 MiB for 10 seconds.This is item D5 of a review of the MicroVM safeguards. The JS SDK gets the same rule and message in aws/aws-durable-execution-sdk-js#1088.
Changes
MAX_JOB_INPUT_BYTESis 6 MiB minus 8 KiB, exported next toMAX_RUN_HOOK_PAYLOAD_LENGTH._validate_inputencodes the input once withdumps, the encoder of the job body, and checks its UTF-8 length.MicroVM "<name>": the job input is <n> bytes as JSON. The limit is <limit> bytes, because the worker accepts a job body of at most 6 MiB. Pass larger data by reference, for example as an S3 key.handle_expect_100,discard_unread_body, and their constants.worker.pyloses 95 lines net.Connection: close.Expect: 100-continue, it gets100 Continue, then the 400. No path hangs, and no path runs the job.Upgrade note
An execution that started on an earlier build, with an input in the last 8 KiB below the old limit, fails at its next replay. The packages are unpublished, and the best-practices docs say to let executions from an earlier build end before deploying a new one.
Testing
JobRequest.to_json(). Within the API models (a MicroVM ID of at most 256 characters, a callback ID of at most 1,024 base64 characters), they take at most 2,692 bytes. With every character of both IDs escaped, they take 7,812 bytes, still under 8 KiB.vm.invokeover the limit creates no job operation.microvmat the limit runs through the real worker.Expect, gets a 400 or a reset, never a hang or a 202.hatch run dev-extras:cov: 386 tests, 100 %.hatch run dev-microvm-worker:cov: 449 tests,worker.py100 %. Typecheck andhatch fmt --checkpass. A stress run with-n 8passed 3 times on macOS and 3 times on Linux.By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.