fix: round-trip serdes result on first run across ops - #550
Conversation
6a28b7a to
e1293c7
Compare
315a90c to
cd7a3c4
Compare
b4f4ddf to
3d1eef0
Compare
249c4e7 to
6a57868
Compare
This comment has been minimized.
This comment has been minimized.
6a57868 to
7db4a57
Compare
This comment has been minimized.
This comment has been minimized.
7db4a57 to
782f6db
Compare
145bc82 to
925cbee
Compare
This comment has been minimized.
This comment has been minimized.
| fs_serdes = FileSystemSerDes("/nonexistent/readonly/path") | ||
|
|
||
| with pytest.raises(ExecutionError, match="Serialization failed"): | ||
| with pytest.raises(SerDesError, match="Serialization failed"): |
There was a problem hiding this comment.
should this be raising RetryableSerDesError or SerDesError in the new world?
There was a problem hiding this comment.
SerDesError is ExecutionError and RetryableSerDesError is InvocationError, so this is correct. However, we can rework filesystem serdes now that we have new error.
925cbee to
a62be70
Compare
a62be70 to
4e647e0
Compare
4e647e0 to
d05e7f4
Compare
This comment has been minimized.
This comment has been minimized.
d05e7f4 to
6afedae
Compare
|
re A collision here means except StepError: misses a real step failure and except SerDesError: catches a non-serdes one could be an idea to store the namepssced class name rather than the short/bare class name? i.e collisions become difficult... To collide, a user would have to ship a module literally named aws_durable_execution_sdk_python.exceptions containing a class of the same name. At which point they've shadowed the SDK's own import path and have gone to a fair degree of trouble. |
6afedae to
eebd0ac
Compare
Codex AI review
Reviewed commit |
| # Namespaced wire token used as the checkpoint ErrorType discriminator. | ||
| # Matching on this rather than the bare class name prevents a user | ||
| # exception coincidentally named "SerDesError" from being misidentified. | ||
| WIRE_ERROR_TYPE: str = "aws_durable_execution_sdk_python.exceptions.SerDesError" |
There was a problem hiding this comment.
f"{__module__}.{__qualname__}"?
Also, so only this one type gets a namespaced token and eight others get bare class names? So the ErrorType field now carries two conventions.
You could argue this is the only discriminant the SDK branches on to choose a raised type, so this bare-names for the others are fine and this one is special?
If you want to go the other way for consistency, a relatively light way of enforcing this for the others is something like this in ErrorObject.from_exception?
cls_ = type(exception)
module: str = "" if cls_.__module__ == "builtins" else f"{cls_.__module__}."
wire_type: str = f"{module}{cls_.__qualname__}"
type=wire_type"
This would give you ValueError rather than builtins.ValueError, and everything else full.y qualified.
this would also mean to change
_DURABLE_OPERATION_ERROR_REGISTRY to derived from the classes rather than typed by hand.
And raise_as_operation_error's comparison to use the same derived expression for SerDesError.
There was a problem hiding this comment.
We can do this to make it consistent, but should be a separate change.
And this change means we are accepting that python will differ in convention with other SDKs.
Claude AI reviewReview: fix: round-trip serdes result on first run across opsI reviewed the complete SHA-anchored diff plus the surrounding source ( Verified correct
No actionable code findings.Residual test riskThe map/parallel parent-level Reviewed commit |
Issue #, if available:
#406
#544
Description of changes:
When a step, child context, or wait_for_condition finishes, we now serialize its result and deserialize it back before saving the SUCCEED checkpoint. The value the function returns on the first run is the deserialized one - exactly what it would return on replay.
Before this, the first run returned the raw in-memory result, but replay returned the value rebuilt from the checkpoint. With a custom serdes that changes the value in transit, those two could differ. Running the round-trip up front makes the first run and replay always agree, and guarantees a SUCCEEDED result is always reconstructable.
Serdes failures are now clearly split:
Behavior changes to note
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.