Count consumed pending states against the bound
CI / ci (push) Successful in 8m9s
CI / ci (pull_request) Successful in 8m11s

A consumed state left the map at once but stayed in the queue until it
expired, so starting and completing flows grew the queue past the bound.
The bound now counts the queue.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-11 01:48:57 -04:00
co-authored by Claude Opus 5.5
parent 0f7f8014f8
commit 085456b65e
2 changed files with 5 additions and 2 deletions
+2 -1
View File
@@ -889,11 +889,12 @@ func TestPendingStates(t *testing.T) {
t.Error("Consume of an unknown state = true")
}
for i := range maxPendingStates {
for i := range maxPendingStates - 1 {
if err := p.Add(fmt.Sprint("s", i), now); err != nil {
t.Fatalf("Add %d: %v", i, err)
}
}
// "first" was consumed but has not expired, so it still counts.
if err := p.Add("over", now); !errors.Is(err, ErrTooManyPending) {
t.Errorf("Add past the bound = %v, want ErrTooManyPending", err)
}
+3 -1
View File
@@ -200,7 +200,9 @@ func (p *PendingStates) Add(state string, now time.Time) error {
expired++
}
p.order = p.order[expired:]
if len(p.states) >= maxPendingStates {
// The bound counts every unexpired state, consumed or not: a consumed
// state leaves states at once but order only when it expires.
if len(p.order) >= maxPendingStates {
return ErrTooManyPending
}
expires := now.Add(p.ttl)