J25 A-293: a placed module's failed newest build said as refused in by-entries mode, on the builder's build-ended event
Reading the catalog half by fingerprint, the node-engine no longer reads the builder's builds, so #224's refused key was never written there and a reader waited on a build that will never be done. The engine now hears the builder's build.ended stream, read whole at start then followed (as the assigner hears it); the last trunk end of a placed module that ended failed is written as the refused key with the event's words, a later done end deletes it, an end naming a branch moves nothing. The manifest consumes mesh-delivery-builder.build.ended.**. Builds: design 47 G A-293 (with §421, §628), ADR 0593 §6, issue 1966 U1/U8 Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
@@ -204,6 +204,12 @@ type Composer struct {
|
||||
// node's own consumer (NoteRunning), under mu; heardRead is whether the first read of the stream ended (RunningRead).
|
||||
heard map[string]map[string]heardRun
|
||||
heardRead bool
|
||||
// ends is, by module, the last build end naming no branch the builder said of it (NoteBuildEnded), its newest build that
|
||||
// ended, under mu; endsRead is whether the first read of the builder's stream ended (BuildEndsRead) (design 47 G A-293).
|
||||
ends map[string]builds.BuildEnded
|
||||
endsRead bool
|
||||
// endFPs is, by module, every fingerprint a trunk end was heard of: the keys a failed end may have written.
|
||||
endFPs map[string]map[string]bool
|
||||
// engine is the node-engine's own module as the last composing of the node's input found it (Scope.Engine), under mu.
|
||||
engine string
|
||||
// rehand asks for a pass that hands again what the agent waits for (Waiting).
|
||||
@@ -2443,6 +2449,50 @@ func (c *Composer) RunningLost() {
|
||||
c.mu.Unlock()
|
||||
}
|
||||
|
||||
// NoteBuildEnded takes the builder's event build.ended (design 47 G A-293): of a module, the last end naming no branch (the
|
||||
// trunk's) stands as its newest build that ended, a failed one said as a refusal in the composition state, a done one ending
|
||||
// that refusal; an end naming a branch moves nothing. Once the first read of the stream ended, an end of a module placed here
|
||||
// asks a pass.
|
||||
func (c *Composer) NoteBuildEnded(e builds.BuildEnded) {
|
||||
if e.Module == "" || e.Fingerprint == "" || e.Branch != "" {
|
||||
return
|
||||
}
|
||||
c.mu.Lock()
|
||||
if c.ends == nil {
|
||||
c.ends, c.endFPs = map[string]builds.BuildEnded{}, map[string]map[string]bool{}
|
||||
}
|
||||
if c.endFPs[e.Module] == nil {
|
||||
c.endFPs[e.Module] = map[string]bool{}
|
||||
}
|
||||
c.endFPs[e.Module][e.Fingerprint] = true
|
||||
if had, ok := c.ends[e.Module]; ok && had.Fingerprint == e.Fingerprint && had.Outcome == e.Outcome && had.Error == e.Error {
|
||||
c.mu.Unlock()
|
||||
return
|
||||
}
|
||||
c.ends[e.Module] = e
|
||||
ask := c.endsRead
|
||||
c.mu.Unlock()
|
||||
if ask {
|
||||
c.askRehand()
|
||||
}
|
||||
}
|
||||
|
||||
// BuildEndsRead says the first read of the builder's stream ended: from now the composer acts on the ends it heard, and a
|
||||
// pass is asked.
|
||||
func (c *Composer) BuildEndsRead() {
|
||||
c.mu.Lock()
|
||||
c.endsRead = true
|
||||
c.mu.Unlock()
|
||||
c.askRehand()
|
||||
}
|
||||
|
||||
// BuildEndsLost says the builder's stream is not followed any more: what was heard is not acted on until a new read ends.
|
||||
func (c *Composer) BuildEndsLost() {
|
||||
c.mu.Lock()
|
||||
c.endsRead = false
|
||||
c.mu.Unlock()
|
||||
}
|
||||
|
||||
func (c *Composer) askRehand() {
|
||||
select {
|
||||
case c.rehand <- struct{}{}:
|
||||
|
||||
Reference in New Issue
Block a user