feat: add payload offloader core runtime - #649
Conversation
This comment has been minimized.
This comment has been minimized.
Claude AI reviewPayload Offloader (Approach B) — reviewThe change is well-structured: a versioned Two confirmed defects, both surfacing only when an offloader is configured (the intended production setup):
Residual test risk: No test covers a Reviewed commit |
625b1d3 to
d190318
Compare
d190318 to
596734d
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
| return executionManager | ||
| .getPayloadCodec() | ||
| .deserialize( | ||
| result, | ||
| resultTypeToken, | ||
| resultSerDes, | ||
| payloadOffloader, | ||
| payloadContext(payloadKind, attempt)); |
There was a problem hiding this comment.
Codex AI review · Finding arf_v1_f3atcijds7gzk56a5jhfbcgnaz
[P1] Latch payload failures before exposing them to handler code. On replay, this runs inside DurableFuture.get(). A handler can catch a load, digest, or ownership PayloadOffloadException and return a fallback, allowing SUCCEEDED despite unreadable checkpoint state. Call ExecutionManager.failInvocation before rethrowing operation codec failures, and test a handler that catches a failing replay load.
| if (unwrapped instanceof UnrecoverableDurableExecutionException) { | ||
| completionInitiated = true; | ||
| ExceptionHelper.sneakyThrow(unwrapped); | ||
| } | ||
| throw failure; |
There was a problem hiding this comment.
Codex AI review · Finding arf_v1_etwwdfzpfwr42v2wd3posft7nz
[P1] Claim ordinary checkpoint failures while holding this lock. A custom DurableExecutionClient.checkpoint may throw a plain runtime exception, which bypasses this UnrecoverableDurableExecutionException branch. The lock is then released with completion still available, allowing a waiting coordinator to persist early parent success before the child terminates. Normalize all checkpoint publication failures to an invocation-level type or otherwise distinguish and claim them here; add a one-shot IllegalStateException race test.
| return serializeAndDeserializeResult(result, SerDesPayloadKind.RESULT, null); | ||
| } | ||
|
|
||
| /** Serializes a result with explicit payload kind and attempt metadata. */ | ||
| protected SerializedResult<T> serializeAndDeserializeResult( | ||
| T result, SerDesPayloadKind payloadKind, Integer attempt) { | ||
| var serialized = serializePayload(result, resultSerDes, payloadKind, attempt); | ||
| var deserialized = | ||
| shouldDeserializeAfterSerialization() ? deserializeResult(serialized, payloadKind, attempt) : result; |
There was a problem hiding this comment.
Codex AI review · Finding arf_v1_im5jt6pypylf7lqfdngnda7mil
[P2] Do not offload transient condition initialization. This helper now offloads, but WaitForConditionOperation.start() still uses it only to normalize initialState; that envelope is never checkpointed. Each first execution can therefore create an orphan external payload and fail on unnecessary storage access before the first check. Use normalizeResult for the initial state and test the offload count and payload contexts.
Codex AI reviewFound three correctness issues: payload failures can be masked, checkpoint races can persist invalid parent success, and condition initialization creates orphan offloads. Reviewed commit |
Stack
Depends on #678, which owns ADR-006 and the architecture decision.
Scope
PayloadOffloaderAPI, SDK-owned payload envelope, producer context, integrity metadata, and invocation-scoped codec/cacheIntentionally excluded from this PR:
Validation
git diff --checkmvn spotless:checkRelated to #463.