Files
mesh-catalog/modules/postgres/cmd/postgres-provider/early_test.go
T
mesh-tools 6005c6001e
mesh/merge-gate head 6005c6001e2f merged into trunk 832a0afd1814 — pass: builds keycloak, postgres, sent nowhere; no bus step; 3 wait(s) for a person; ever…
mesh/repo-check head 6005c6001e2f merged into trunk 832a0afd1814 — pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-…
mesh/delivery delivered
Ask the plans again when the moved path starts before its runtime answers (issue 943)
postgres and keycloak start their moved path beside Serve, and a watch
asked before Serve runs is refused by the runtime. Run returned on that
refusal and main only logged it, so a start that lost the race left the
provider answering nobody and retiring nothing until its next restart:
postgres on novox at 16:52, 18:29 and 18:48, on ace at 16:22, which kept
issue 937's retirement condition on novox from clearing. Run now asks
again, the wait doubling from a second to a minute, until the runtime
answers or its context ends.
2026-10-16 16:52:52 +00:00

63 lines
1.7 KiB
Go

package main
// The moved path started before its runtime answers asks again until it does (issue 943).
import (
"context"
"errors"
"testing"
"time"
"git.novox.be/novox/mesh-sdk/go/provider"
)
// earlyBus refuses its first watches as the runtime does before Serve runs, then answers as the bucket bus does.
type earlyBus struct {
*bucketBus
refuse int
}
func (b *earlyBus) Watch(ctx context.Context, bucket string, handle func(string, []byte)) error {
if b.refuse > 0 {
b.refuse--
return errors.New("before Serve: a bundle reaches the bus through the runtime that launched it")
}
return b.bucketBus.Watch(ctx, bucket, handle)
}
func TestAMovedPathStartedTooEarlyAsksAgainUntilTheRuntimeAnswers(t *testing.T) {
w := newMovedWorld(t, map[[2]string]string{})
w.run.FirstRetry = time.Millisecond
w.run.loaded = false
bus := &earlyBus{bucketBus: w.bus, refuse: 3}
p := provider.New(provider.Options{Node: "novox", Module: "postgres", Bus: w.bus,
Vault: provider.ConsumersFile{Paths: []string{w.file}}, Make: w.run.Make, Gone: w.run.Gone,
Every: time.Hour, Logf: func(string, ...any) {}})
ctx, cancel := context.WithCancel(context.Background())
done := make(chan error, 1)
go func() { done <- w.run.Run(ctx, p, bus) }()
deadline := time.After(time.Second)
for {
w.run.mu.Lock()
loaded := w.run.loaded
w.run.mu.Unlock()
if loaded {
break
}
select {
case err := <-done:
cancel()
t.Fatalf("Run stopped before the runtime answered: %v", err)
case <-deadline:
cancel()
t.Fatal("the plans were never watched")
case <-time.After(time.Millisecond):
}
}
cancel()
<-done
if bus.refuse != 0 {
t.Fatalf("%d refusals left", bus.refuse)
}
}