[workflows] Add Workflow rollback support#13983
Conversation
🦋 Changeset detectedLatest commit: 3ffb097 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
✅ All changesets look good |
|
Review posted successfully on PR #13983. I found two actionable issues:
|
create-cloudflare
@cloudflare/kv-asset-handler
miniflare
@cloudflare/pages-shared
@cloudflare/unenv-preset
@cloudflare/vite-plugin
@cloudflare/vitest-pool-workers
@cloudflare/workers-editor-shared
@cloudflare/workers-utils
wrangler
commit: |
|
/bonk |
|
Review posted successfully on PR #13983. I found two actionable issues:
I also noted that the fatal abort paths ( Both issues from the previous review (closure guard, streamOutput handling in |
|
/bonk |
There was a problem hiding this comment.
I'm Bonk, and I've reviewed your PR after the latest lint-fix commit (6f338dd).
Previously flagged issues — status:
- Closure guard (
context.ts:226) — Fixed. Thetypeof closure !== "function"guard is in place. readLogs/readDetailedLogsstreamOutput handling (engine.ts:111-116) — Fixed. TheisStepSuccessEvent()helper correctly covers bothSTEP_SUCCESSandROLLBACK_STEP_SUCCESS.forloop braces (rollback.ts:146-148) — Fixed. Braces added.- Non-null assertion on rollback cache key (
context.ts:299-301) — Fixed. Now narrows viaconst rollbackStep = this.#rollbackStep.
Remaining issue:
- Non-null assertions on array index (
rollback.ts:126,rollback.ts:147) —entries[i]!uses non-null assertions which violate the repo's@typescript-eslint/no-non-null-assertion: errorrule (.oxlintrc.jsonc:47). While the index is always in-bounds due to the loop condition, the linter doesn't know that. The fix is to use an intermediate variable or useat()with a guard. See inline comments.
Overall: The implementation is clean and well-structured. Rollback execution through Context.do is a smart reuse of existing retry/timeout/logging machinery. The LIFO ordering via SQL STEP_START events is correct, test coverage is thorough, and the changeset is well-written. One lint issue remains to address.
|
Review posted successfully on PR #13983. Here's a summary: Previously flagged issues — all addressed:
One remaining issue found:
|
|
/bonk |
There was a problem hiding this comment.
I'm Bonk, and I've reviewed the latest state of the PR (d1ba1fb).
All previously flagged issues are resolved:
- Closure guard (
context.ts:226) — Fixed.typeof closure !== "function"guard in place. readLogs/readDetailedLogsstreamOutput handling (engine.ts:111-116) — Fixed.isStepSuccessEvent()helper covers bothSTEP_SUCCESSandROLLBACK_STEP_SUCCESS.forloop braces (rollback.ts:146-148) — Fixed.- Non-null assertion on rollback cache key (
context.ts:299-301) — Fixed viaconst rollbackStep = this.#rollbackStepnarrowing. - Non-null assertions on array index (
rollback.ts:125, 146-148) — Fixed. Now usesfor...ofwithentries.entries()and.slice()destructuring, eliminating allentries[i]!patterns.
No new issues found. The implementation is clean — rollback execution through Context.do is a smart reuse of retry/timeout/logging machinery, LIFO ordering via SQL STEP_START events is correct, and test coverage is thorough. LGTM.
|
Review posted on PR #13983. All five issues raised across the previous three review rounds have been properly addressed in the latest commits. No new issues found — the PR looks good. |
|
/bonk review |
There was a problem hiding this comment.
I've reviewed the full PR. All five issues raised across the previous four review rounds have been properly addressed:
- Closure guard (
context.ts:226) —typeof closure !== "function"guard is in place. readLogs/readDetailedLogsstreamOutput handling (engine.ts:111-116) —isStepSuccessEvent()helper correctly covers bothSTEP_SUCCESSandROLLBACK_STEP_SUCCESS.forloop braces (rollback.ts:146-148) — Fixed.- Non-null assertion on rollback cache key (
context.ts:299-301) — Fixed viaconst rollbackStep = this.#rollbackStepnarrowing. - Non-null assertions on array index (
rollback.ts:125, 146-148) — Fixed. Now usesfor...ofwithentries.entries()and.slice()destructuring.
The implementation is well-structured. A few highlights:
- Smart reuse of
Context.dofor rollback execution means rollbacks automatically inherit retry, timeout, and attempt-logging machinery without duplicating any of that logic. - LIFO ordering via SQL
STEP_STARTevents is correct and matches the service implementation. The fallback to registry insertion order for entries missing from SQL (edge case) is a good defensive measure. - Event model is clean — the new
ROLLBACK_*events (17-25) are sequential, theisStepSuccessEventhelper keeps thereadLogs/readDetailedLogsstream handling DRY, and rollback steps don't count against the step limit. - RPC stub lifecycle is handled correctly:
dup()on registration,Symbol.disposeon cleanup,clearRollbackRegistryon success, and dispose of remaining entries on rollback chain halt. - Test coverage is thorough — LIFO ordering, parallel step ordering, rollbackConfig propagation, rollback context correctness, failed-step rollbacks, partial registration, chain-halt on failure, and no-rollback-on-success.
No new issues found. LGTM.
|
Review posted and approved on PR #13983. All previously raised issues have been addressed, and no new issues were found. The implementation is solid — rollback execution through |
|
Codeowners approval required for this PR:
Show detailed file reviewers |
fa8b197 to
90e7632
Compare
Co-authored-by: Olga Silva <78314353+pombosilva@users.noreply.github.com>
|
/bonk |
There was a problem hiding this comment.
I've reviewed all the outstanding feedback against the current state of the branch. Everything has already been addressed:
@pombosilva's comments:
- Changeset title (
.changeset/saga-rollbacks.md:5) — Already updated to "Add rollback support for local Workflows development" (no "saga"). - Remove PR reference (
.changeset/saga-rollbacks.md:11) — Already removed; now just mentions theworkflows_step_rollbackcompat flag without referencingcloudflare/workerd#6330. - Move
parseRollbackOptionstorollback.ts(context.ts) — Already done. The function lives inrollback.ts:43-84and is imported incontext.ts:18. - Blank line before
ROLLBACK_START(instance.ts:128) — Already present at line 127.
Devin review:
- Clear
rollbackRegistryinattemptResume(engine.ts) — Already handled atengine.ts:1019withclearRollbackRegistry(this.rollbackRegistry).
No remaining unaddressed feedback found.
|
I reviewed all outstanding feedback on PR #13983. All five items from @pombosilva and Devin's review have already been addressed in the current state of the branch:
Posted a review comment confirming this on the PR. |
90e7632 to
3ffb097
Compare
petebacondarwin
left a comment
There was a problem hiding this comment.
The changes here are all local to the workflows-shared package, so delegating full review and approval to the workflows team (e.g. @pombosilva).
Looked through the code and don't see any logical issues, but have not validated whether the behaviour is expected from a product point of view.
Approving on behalf of workers-sdk in general.
workers-devprod
left a comment
There was a problem hiding this comment.
Codeowners reviews satisfied
Co-authored-by: Olga Silva <78314353+pombosilva@users.noreply.github.com>
Add saga rollback support to the local Workflows engine used by Wrangler dev.
Workflow steps can now register rollback handlers through trailing
step.do()options and the local engine runs those handlers when the workflow fails. Rollbacks execute through rollback scopedContext.do()calls so they reuse the existing retry, timeout, attempt logging and step bookkeeping pathsThis also aligns local rollback behavior with the service implementation by:
A picture of a cute animal (not mandatory, but encouraged) (his name's leo)
