inspect: make RunMulti fan-in capacity explicit · Entire

inspect: make RunMulti fan-in capacity explicit

9cfadf9→main·

dipree·4w ago·2 files·+38 added/-4 removed

Replace the len(reviewers)17 fan-in capacity expression with named event-slack and terminal-slot terms. The capacity is still 16N event slots plus N terminal slots, making it explicit that all queued Start-failure terminals fit even when every reviewer fails to start.

Add a regression with more than 17 all-start failures to pin the capacity invariant and completion behavior.

Sessions

ba4a2811b160View transcript

[?
Checkout the hand off doc that I just added.Pi·Opus 4.8·1 step](/content/gh/entireio/cli/session/019eca64-8c2c-7b00-90c6-3aa49738c497#timeline-ba4a2811b160/index.html)

Changes

2

130 unmodified lines

131
132
133
134
135
136
137
134
135
136
137
138
139
140
141
142
143
144

130 unmodified lines

}

// fanIn carries tagged events from N agent goroutines into the single
    // dispatch loop. Reserve len(reviewers)*16 slots for event-burst jitter plus
    // one terminal-marker slot per reviewer, so queued Start-failure terminals
    // cannot consume the event-burst slack before the dispatch loop starts.
    fanIn := make(chan taggedEvent, len(reviewers)*17)
    // dispatch loop. Reserve event-burst slack plus one terminal-marker slot per
    // reviewer, so the worst case of every reviewer failing Start fits entirely in
    // the terminal reservation without consuming event slack.
    const eventBurstSlotsPerReviewer = 16
    reviewerCount := len(reviewers)
    targetSlots := reviewerCount
    fanInCapacity := reviewerCount*eventBurstSlotsPerReviewer + targetSlots
    fanIn := make(chan taggedEvent, fanInCapacity)

// Each reviewer runs under its own deadline (unless reviewerTimeout returns
    // 0, meaning disabled) so a stuck agent is cancelled without hanging the run;

Mcmd/entire/cli/review/run_multi.go+8/-4

181 unmodified lines

182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217

181 unmodified lines

}
}

func TestRunMulti_AllStartErrorsOverSeventeenStillFinish(t *testing.T) {
    t.Parallel()
    const reviewerCount = 32
    reviewers := make([]reviewtypes.AgentReviewer, 0, reviewerCount)
    for i := range reviewerCount {
        reviewers = append(reviewers, &stubReviewer{name: fmt.Sprintf("bad-%02d", i), startErr: fmt.Errorf("start failed %d", i)})
    }
    type result struct {
        summary reviewtypes.RunSummary
        err     error
    }
    done := make(chan result, 1)
go func() {
        summary, err := RunMulti(context.Background(), reviewers, reviewtypes.RunConfig{}, nil)
        done <- result{summary: summary, err: err}
    }()

select {
    case res := <-done:
        if res.err == nil {
            t.Fatal("RunMulti error = nil, want a start error")
        }
        if len(res.summary.AgentRuns) != reviewerCount {
            t.Fatalf("AgentRuns = %d, want %d", len(res.summary.AgentRuns), reviewerCount)
        }
    case <-time.After(2 * time.Second):
        t.Fatal("RunMulti deadlocked with more than 17 all-start-failure terminals")
    }
}

func TestRunMulti_AllStartErrorsStillFinish(t *testing.T) {
    t.Parallel()
    firstErr := errors.New("first start failed")