diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/halves.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/halves.go index 558657ac..49f8a57c 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/halves.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/halves.go @@ -51,9 +51,39 @@ func (h *halves) follow() error { h.mu.Lock() h.branches = b h.mu.Unlock() + h.settleWhenNoBranch() return nil } +// settleWhenNoBranch tells the first pass once, when the registrations and the gate's source are answered and name no branch: the +// trunk is none-yet and the world is empty, as the catalog client's Ready says it (design 47 G, A-372). A mesh that names a branch is +// told by adopted, when that branch's first view is answered. +func (h *halves) settleWhenNoBranch() { + if h.settled == nil { + return + } + h.mu.Lock() + b := h.branches + h.mu.Unlock() + go func() { + select { + case <-b.FirstViews(h.ctx): + case <-h.ctx.Done(): + return + } + if len(b.Followed()) > 0 || b.Ready() != nil { + return + } + h.mu.Lock() + told := h.told + h.told = true + h.mu.Unlock() + if !told { + h.settled <- struct{}{} + } + }() +} + // first is the first watched branch followed, the trunk's: "" while none is. func (h *halves) first() string { h.mu.Lock()