A first merge into a new repository waits kept for mesh-delivery's word, and the word's arrival asks the builds, with no timer; AC7 on the bus in both orders (issue 1146)

This commit is contained in:
2026-10-19 00:16:36 +02:00
parent 19f15d8ea0
commit 4e12fc19b7
9 changed files with 301 additions and 87 deletions
+10
View File
@@ -84,6 +84,16 @@ func (i *Inventory) AloneMerges(ctx context.Context) ([]BatchedMerge, error) {
return i.chainAloneMerges(ctx, c)
}
// WaitingMerges is every merge no plan answers that is not walked alone: kept, and waiting for something else to
// happen to it (a first merge into a repository, waiting for mesh-delivery's word on it, issue 1146).
func (i *Inventory) WaitingMerges(ctx context.Context) ([]BatchedMerge, error) {
c, err := i.theChain(ctx)
if err != nil {
return nil, err
}
return i.chainWaitingMerges(ctx, c)
}
// AnswerMerge moves a merge to the plan that answers it now; an empty plan with alone leaves it waiting to
// be walked on its own commit.
func (i *Inventory) AnswerMerge(ctx context.Context, repository, commit, plan string, alone bool) error {
+16
View File
@@ -452,6 +452,22 @@ func (i *Inventory) chainAloneMerges(ctx context.Context, c *chain.Chain) ([]Bat
return out, nil
}
// chainWaitingMerges is every merge no plan answers that waits and is not walked alone, the newest first.
func (i *Inventory) chainWaitingMerges(ctx context.Context, c *chain.Chain) ([]BatchedMerge, error) {
w, err := i.chainWinners(ctx, c)
if err != nil {
return nil, err
}
var out []BatchedMerge
for _, h := range w {
if h.m.Waiting && !h.m.Alone {
out = append(out, batchedOf(h))
}
}
sortMerges(out, true)
return out, nil
}
// pendingMerge is a merge added to a plan that is not saved yet: carried until that plan's save writes it.
type pendingMerge struct {
plan string
+33
View File
@@ -0,0 +1,33 @@
package inventory
import (
"context"
"testing"
"time"
)
// A merge no plan answers waits, and is listed as waiting until it is answered where it is kept (novox/hq issue 1146):
// what a first merge into a new repository does while it waits for mesh-delivery's word.
func TestAMergeNoPlanAnswersIsListedWaitingUntilItIsAnswered(t *testing.T) {
inv, c := anInventoryOnTheChain(t)
ctx := context.Background()
now := time.Now().UTC()
if added, err := inv.chainAddMerge(ctx, c, BatchedMerge{Repository: "novox/mesh-delivery", Branch: "main", Commit: "c1",
Merged: now, Heard: now}); err != nil || !added {
t.Fatalf("added %v, %v", added, err)
}
waiting, err := inv.chainWaitingMerges(ctx, c)
if err != nil || len(waiting) != 1 || waiting[0].Commit != "c1" {
t.Fatalf("waiting %+v, %v", waiting, err)
}
move := []MergeMove{{Repository: "novox/mesh-delivery", Commit: "c1", Plan: WaitingRecord}}
if err := inv.chainSavePlans(ctx, c, nil, move); err != nil {
t.Fatal(err)
}
if waiting, err = inv.chainWaitingMerges(ctx, c); err != nil || len(waiting) != 0 {
t.Fatalf("answered, it still waits: %+v, %v", waiting, err)
}
if _, known, err := inv.chainMergeOf(ctx, c, "novox/mesh-delivery", "c1"); err != nil || !known {
t.Fatalf("an answered merge is no longer kept: %v %v", known, err)
}
}