Start the puller's capacity watch once Serve has the runtime's channel, since a build module pulls before it serves (issue 1887)

A watch asked before Serve is refused, which would have left every build
module on its settings file again. stdio.Served closes when Serve has the
channel; WatchConfigServed waits on it, and Pull starts the watch beside its
loop.
This commit is contained in:
2026-10-25 17:26:10 +01:00
parent e6b2df6506
commit b9911dc1c1
3 changed files with 45 additions and 2 deletions
+10 -2
View File
@@ -70,7 +70,8 @@ type Puller struct {
// a restart.
Load func(key string) ([]byte, error)
// WatchConfig, when set, follows the module's config value `capacity` (CapacitySetting) as mesh-config resolves it
// for this node: stdio.WatchConfig in a module, a test's own double.
// for this node, and wakes the puller on each change (watchCapacity): WatchConfigServed in a module, a test's own
// double. Until it hands a value the puller judges by Capacity.
WatchConfig func(key string, handle func(stdio.ProvisionChange) error) error
mu sync.Mutex
@@ -228,7 +229,7 @@ func (p *Puller) Pull(ctx context.Context) error {
if err := p.restore(); err != nil {
return err // pulling on a pause that cannot be read could build on a node paused on purpose
}
p.watchCapacity()
go p.watchCapacity() // WatchConfigServed waits for Serve, which a module starts after its pull
wait := p.PullWait
if wait <= 0 {
wait = DefaultPullWait
@@ -409,6 +410,13 @@ func (p *Puller) watchCapacity() {
}
}
// WatchConfigServed is stdio.WatchConfig once Serve has the runtime's channel (stdio.Served): a build module starts its
// pull before it serves, and a watch asked before that would be refused.
func WatchConfigServed(key string, handle func(stdio.ProvisionChange) error) error {
<-stdio.Served()
return stdio.WatchConfig(key, handle)
}
// capacityFrom is the node's capacity in one value the watch handed, and why it is 0 when it cannot be read.
func (p *Puller) capacityFrom(c stdio.ProvisionChange) (int, string) {
if c.Refused != "" {