Count an unasked report as said only once the broker has taken it (hq ADR 0100)

This commit is contained in:
2026-09-22 20:00:59 +02:00
parent b4c21b4f67
commit 01e8affa89
3 changed files with 63 additions and 13 deletions
+26 -8
View File
@@ -638,11 +638,11 @@ func runLink(ctx context.Context, opts options) error {
// (novox/hq ADR 0004).
// Reports a reconcile has to make unasked — what an adopted node holds changed, or its
// firewall did — go out over the link when it is up (novox/hq ADR 0100).
outbox := make(chan link.Report, 1)
outbox := make(chan link.Unasked, 1)
watch := &adoptionWatch{}
applier = watch.noting(applier)
go holdTheMachine(ctx, opts, mine, say, sched, func(r link.Report) {
if !watch.changed(r) {
if !watch.differs(r) {
return
}
select {
@@ -650,7 +650,13 @@ func runLink(ctx context.Context, opts options) error {
// An older one nobody has published yet; this one says everything it did.
default:
}
outbox <- r
// Counted as said only once the broker has taken it: queued and lost — the link down, the
// publish refused — the change would never be said again (novox/hq ADR 0100).
outbox <- link.Unasked{Report: r, Done: func(published bool) {
if published {
watch.said(r)
}
}}
})
return link.HoldRoused(ctx, link.Membership{
@@ -686,15 +692,27 @@ func adoptionFingerprint(r link.Report) string {
return strings.Join(parts, "\n")
}
// changed records a report and says whether it differs from the last one that went out.
func (w *adoptionWatch) changed(r link.Report) bool {
// differs says whether a report says anything the last one that went out did not. It records
// nothing: what was said is what reached the mesh, not what was written down to send.
func (w *adoptionWatch) differs(r link.Report) bool {
w.mu.Lock()
defer w.mu.Unlock()
now := adoptionFingerprint(r)
if now == w.last {
return adoptionFingerprint(r) != w.last
}
// said records a report the mesh has actually been told.
func (w *adoptionWatch) said(r link.Report) {
w.mu.Lock()
defer w.mu.Unlock()
w.last = adoptionFingerprint(r)
}
// changed is differs and said together, for a report published as it is made.
func (w *adoptionWatch) changed(r link.Report) bool {
if !w.differs(r) {
return false
}
w.last = now
w.said(r)
return true
}