Repository navigation
Reuse side effects and version markers in redrive (#980) - #1175
Merged
Merged
Conversation
Native redrive refused any failed run whose history held a side effect, version marker or workflow-code upsert (unsupported_history). Core's FailedRunRedrivePlan (workflow#991) reuses those steps before the failed one: the successor records each in step order with the source payload, minus its task and command, plus reused_from_run_id and the time the step first ran as reused_recorded_at. The plan now takes SideEffectRecorded, VersionMarkerRecorded, MemoUpserted and SearchAttributesUpserted steps with Core's refusals (invalid_step_sequence, duplicate_step_sequence, external_side_effect_result_not_supported, invalid_failed_step, activity_sequence_gap). Upserted visibility rows must match a reused upsert step (rowsMatchReusedUpserts). A reused upsert refuses with service_redrive_history_not_qualified, as Core refuses it for a service worker's run, since native runs every workflow on a service worker. Refs #980 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Refs #980. Slice 3 (Core workflow#991, fixture
redrive-reused-markers-clock), after #1162 and #1164.Native redrive refused any failed run whose history had a side effect, version marker or workflow-code upsert, with
unsupported_history. Core'sFailedRunRedrivePlanreuses those steps when they come before the failed step.Change (
rust/src/runtime/redrive.rs)SideEffectRecorded,VersionMarkerRecorded,MemoUpsertedandSearchAttributesUpsertedas one-step markers, as Core's plan does. It refuses with Core's reasons:invalid_step_sequencewhen a marker has no valid sequence or comes before the start.duplicate_step_sequencewhen two markers share a step, or a marker shares one with an activity.external_side_effect_result_not_supportedwhen a side-effect result is stored externally (Core'sexternal_storageor a stored reference, plus native'sexternal_payloadenvelope).invalid_failed_stepwhen a marker is at or after the failed step.activity_sequence_gapwhen activities and markers don't fill every step before the failed one.taskandcommand, and addsreused_from_run_idandreused_recorded_at. That is when the step first ran, kept across a chain of redrives (successorEvents). Reused activities are unchanged.FailedRunRedriveEligibility::rowsMatchReusedUpserts. A memo or search-attribute row that workflow code upserted must match a reused upsert step; otherwise the run refuses withunsupported_visibility_metadata.service_redrive_history_not_qualified. Core does this for a run a service worker started (workflow_definition_fingerprint_source = worker; Core fixtureredrive-service-unqualified-history) because the SDKs can't replay a reused upsert yet. Native applies the check at the same point in Core's order, and again after the definition check. Native runs every workflow on a service worker, so it never accepts a reused upsert.can_redrive/redrive_blocked_reason(Report the redrive decision in describe (#980) #1164) report the same decision with no further change.Core parity evidence (workflow
origin/main2ce626d4, 2.26.0+)src/V2/Support/FailedRunRedrivePlan.php: the marker branch offorRun, the ordering of marker/activity checks after the boundary, andsuccessorEventsfor steps that aren't activities.src/V2/Support/FailedRunRedriveEligibility.php:rowsMatchReusedUpserts, then the service qualification check (reusesServiceUnqualifiedSteps: memo/search-attribute upserts, signals, children and updates are not qualified; side effects and version markers are).redrive-reused-markers-clock(side effect at step 1, version marker at step 2, resume at 4, reused times are the source's) andredrive-service-unqualified-history. Core testtestRedriveReusesSideEffectsAndVersionMarkersAtTheirRecordedTime.Known divergence (safe direction): for a run that Core would treat as embedded-or-unknown (no
workerfingerprint source) with a matching definition, Core accepts reused upserts. Native refuses them because it has no embedded replay.Tests
redrive_reuses_side_effects_and_version_markers_at_their_recorded_time, after the Core fixture. The source records a side effect and a version marker, then activitya, and fails at activityb(step 4); its marker times are backdated. The redrive resumes at 4. The successor's history and the worker's poll replaySideEffectRecorded,VersionMarkerRecordedandActivityCompletedat steps 1–3, each with the source payload (no task/command),reused_from_run_idand the source's originalreused_recorded_at. The worker then schedulesbat step 4. The successor fails again, and its own redrive keeps the first-run times whilereused_from_run_idnames the successor.redrive_carries_start_time_memo_and_search_attributes: a code-upserted memo now reports and refusesservice_redrive_history_not_qualified, in both describe and redrive, before anything is written.plan_reuses_marker_steps_like_corecovers step order, task/command stripping and each new refusal reason.Release notes (for the next native release): Redrive now reuses side effects and version markers recorded before the failed step, as Workflow does. The new run records them with the original payload,
reused_from_run_idand the time they first ran (reused_recorded_at), so workflow time after those steps matches the failed run. A run whose workflow code upserted a memo or search attribute is refused withservice_redrive_history_not_qualified(previouslyunsupported_history) until the SDKs can replay reused upserts. A side effect stored externally is refused withexternal_side_effect_result_not_supported.Remaining #980 slices: fired plain timers (workflow#992,
unsupported_timer/incomplete_timer_step, fixtureredrive-reused-timer-clock). Then, following Core's service-mode qualification: signal waits, updates and completed child workflows (workflow#1109), with their own validation and then the service refusal, plusMessageCursorAdvancedcarryover and theworkflow_code/structural_limitfailure kinds.🤖 Generated with Claude Code