aws / aws/aws-durable-execution-sdk-rust
[Feature]: Exit gracefully with PENDING when a checkpoint response has no CheckpointToken
- Dominant language
- Rust
- Stars
- 13
- Forks
- 0
- Avg merge
- 10m
- Merged PRs (30d)
- 1
Description
### What would you like?
When a checkpoint response arrives without a `CheckpointToken`, the SDK should treat it as a signal that the service will accept no further checkpoints from this invocation. The SDK should stop issuing checkpoints and end the invocation cleanly with `Status: PENDING`.
Why PENDING and not FAILED or a thrown error:
- A missing token does not mean the execution is finished. It means this invocation cannot make further progress. The invocation result must not claim the execution finished.
- A thrown error is an invocation failure. Lambda retries it, but the retry has no valid token and can do nothing useful. It also puts an error in customer logs for a condition the SDK understood.
- PENDING is already what the SDK returns for every suspend (wait, scheduled retry, pending callback). This is a suspend: the invocation is done for now and the execution continues later.
### Current behavior
`src/client.rs` treats a missing token as a non-retryable client error:
https://github.com/aws/aws-durable-execution-sdk-rust/blob/60ea9cf07652872083f0e6dac9b4761a801168ea/src/client.rs#L167
```rust
let new_token = output.checkpoint_token.unwrap_or_default();
if new_token.is_empty() {
return Err(ClientError::non_retryable(
"backend returned no checkpoint token".to_owned(),
));
}
```
`context.rs` `checkpoint_failure_unrecoverable` sees `is_retryable() == false`, writes a terminal FAIL, and fails the execution. So a missing token is an execution failure today. The detection point already exists; only its classification and exit path need to change.
### Possible Implementation
1. Return a distinct outcome from `checkpoint` for the missing-token case (a new `ClientError` kind, or a variant of `CheckpointOutput`), separate from "malformed response".
2. In `context.rs`, route that outcome to the existing suspension path (`suspend_now` / `suspension_signal`) so the invocation driver answers `PENDING`, rather than to `record_invocation_fault` or the terminal-FAIL path.
3. Stop the coalescing checkpoint buffer from issuing further writes; there is no token to send. Queued updates are abandoned and replay on the next invocation. AT_MOST_ONCE steps whose START landed in the last accepted checkpoint will not run again, which is the defined semantics of AT_MOST_ONCE.
4. Unit test: a checkpoint response without `checkpoint_token` produces `PENDING`, no further checkpoint calls, and no recorded fault.
5. Testing support: the local runner needs a way to omit the token on a chosen checkpoint so customers can test their handlers against this path.
### Is this a breaking change?
No. The SDK's response set is unchanged; a new internal suspension cause is added.
### Additional Context
- Prerequisite: https://github.com/aws/aws-durable-execution-sdk-rust/issues/66 (message-case bug in stale-token classification). That fix is the fallback path whenever the missing token is not detected, so it should land first.
- Sibling issues in the other SDKs are linked in a comment below.
Contributor guide
Research direction
Start in src/client.rs at the missing checkpoint-token handling, then trace context.rs through checkpoint_failure_unrecoverable and the suspend_now/suspension_signal path. Add or update tests so a tokenless response returns PENDING, makes no further checkpoint calls, and records no fault; also inspect the local runner support for omitting a token on a chosen checkpoint.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- backend-api-design, testing
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 70/100