diff --git a/cmd/mesh-controller/push.go b/cmd/mesh-controller/push.go index 241a5012..08aa18ac 100644 --- a/cmd/mesh-controller/push.go +++ b/cmd/mesh-controller/push.go @@ -208,6 +208,8 @@ func serve(ctx context.Context) (err error) { if err := server.Follows(following{open: open}); err != nil { return err } + // And the merges it did not hear while it was away, caught up once it serves (novox/hq ADR 0457, issue 1336). + go catchUpAtStart(ctx, open) // And the merges mesh-delivery made, kept a week with the ask each was made on: what registers a module that // moved between repositories on the operator's Approve (novox/hq ADR 0420 ยง7, issue 1025). if err := server.KeepsDeliveryMerges(keepingDeliveryMerges{js: server.JetStream, catalog: open.inventory.Catalogued, diff --git a/cmd/mesh-controller/upgrades.go b/cmd/mesh-controller/upgrades.go index 23efee2d..57a426ee 100644 --- a/cmd/mesh-controller/upgrades.go +++ b/cmd/mesh-controller/upgrades.go @@ -316,7 +316,16 @@ func unsaved(err error) error { // SourceMoved is the forge announcing a merge. It is put into the open batch (novox/hq ADR 0276), which // becomes one walk when its merge window closes: hearMerge, and cutBatchesHeld in batches.go. func (f following) SourceMoved(ctx context.Context, m link.SourceMoved) error { - return f.hearMerge(ctx, m, time.Now().UTC()) + if err := f.hearMerge(ctx, m, time.Now().UTC()); err != nil { + return err + } + // And the merges of that trunk it did not hear, in the trunk's order (novox/hq ADR 0457): a catch-up that leaves + // something for later is no failure of this merge's hearing, and is never a reason to hear it again. + if !f.oneShot { + trunk := &caughtTrunk{Owner: m.Owner, Repo: m.Repo, Branch: m.Base} + catchUpBeside(func() { f.catchUp(context.WithoutCancel(ctx), trunk) }) + } + return nil } // movesOfMerge is what one merge moves, acted on: every module recorded as built from that repository and