diff --git a/internal/link/serve.go b/internal/link/serve.go index b3461a73..c5af8fc4 100644 --- a/internal/link/serve.go +++ b/internal/link/serve.go @@ -668,12 +668,13 @@ func (s *Server) sourceMoved(ctx context.Context, m Control) { return } err := s.upgrader.SourceMoved(ctx, moved) + // Left unsettled when the controller is ending, whatever error that gave (the plans' hold returns a bare + // context.Canceled): the bus hands it to whatever consumes next, and taking it would lose the merge. + if err != nil && ctx.Err() != nil { + return + } if err != nil && errors.Is(err, ErrTryAgain) { - // Left unsettled when the controller is ending (the bus hands it to whatever consumes next, as decide - // does) and when the bus will not hold it: taking it would lose the merge. - if ctx.Err() != nil { - return - } + // Also left unsettled when the bus will not hold it. delay := MergeRedeliverAfter(m.HeldFor()) if held := m.Hold(delay); held != nil { s.log.Printf("%s/%s moved to %.8s and could not be held (%v): %v; left for the bus to hand over again", diff --git a/internal/link/store_window_test.go b/internal/link/store_window_test.go index 6eb8dea7..29ecdfc4 100644 --- a/internal/link/store_window_test.go +++ b/internal/link/store_window_test.go @@ -143,8 +143,9 @@ func TestAMergeIsLeftUnsettledWhenTheControllerEndsOrTheHoldFails(t *testing.T) merged := SourceMoved{Owner: "novox", Repo: "one", Base: "main", Commit: "abcdef0123"} try := errors.Join(ErrTryAgain, errors.New("another controller is working the plans")) + // The plans' hold returns a bare context.Canceled when the controller is replaced, not ErrTryAgain. s, in := serving() - s.upgrader = upgradesWith{err: try} + s.upgrader = upgradesWith{err: context.Canceled} to := &settled{} ended, end := context.WithCancel(context.Background()) end()