Repository navigation
Conversation
A caller that stopped a run through context.WithCancelCause got its cause back bare, so the verdict coded the stop execution-failed instead of cancelled-by-caller. The copier and the catch-up now report the cause wrapped together with ctx.Err(), so errors.Is answers for both.
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.
A run a caller stops through
context.WithCancelCauseis now codedcancelled-by-caller, whatever cause the caller cancelled with.Why
migrate.copySwapFailureCodereads a stop as the caller's when the error answerserrors.Is(err, context.Canceled). The copier returnedcontext.Cause(ctx)fromRun, and the catch-up did the same fromstoppedandholdFlushes, so a caller that cancelled with a cause of its own — an orchestrator saying why it stopped the run — got that cause back bare, with nocontext.Canceledin the chain. The verdict then coded the stopexecution-failed, and an adapter routing on the code treated a deliberate stop as a fault. A plaincancel()was unaffected, since its cause iscontext.Canceled.What
pkg/copier:Runreports why its workers stopped throughstopReason: a worker's own error stands as it is, even when the caller cancelled after it; the caller's ending ofctxis reported throughendedWith.pkg/applier:stoppedandholdFlushesreport the context's end throughendedWith.endedWith(one small copy per package) returnsctx.Err()as it stands for a plain cancel or a passed deadline, and for a cause of the caller's own returns the cause wrapped together withctx.Err()—"<cause> (context canceled)"— soerrors.Isanswers for the cause and forcontext.Canceledalike.copyAndSwapcancellation tests now cancel with a cause and assert both readings, and a newcopyAndSwaptest asserts the verdict code iscancelled-by-caller— it reportsexecution-failedwithout the fix. A new live-run test cancels with a cause during catch-up and resumes to done.Runoutcome and verdict tables inschemabot-integration.md, and thepkg/applierrow in the design doc.One knock-on inside the runner:
captureOutcomedrops the fill's error when it is the capture's cancellation (errors.Is(fillErr, context.Canceled)). A catch-up failure that cancels the fill now wrapsCanceled, so the fill's "my context was cancelled" error is dropped and the catch-up's failure is reported alone, where before both were reported. The classification of every other runner stop (errCaptureEnded, the saver's stop) is unchanged; the existing live-run tests cover them.Before / after
An orchestrator runs a copy-and-swap and stops it mid-copy with
cancel(ownerStop)whereownerStop = errors.New("owner is ready to cut over"). Before, the verdict read as a fault; after, it reads as the caller's stop, and the error still names the caller's cause. Nothing about what the stop leaves behind changes: the row stands incopyingat its last save either way, and the next run resumes from it.A plain
cancel()reads the same on both sides:endedWithreturnscontext.Canceledas it stands, not doubled.🤖 Generated with Amp (Claude Opus 4.6)