fix(queue): prevent applyQueueDropPolicy from selecting in-flight items as overflow victims#103284
Merged
Merged
Conversation
…ms as overflow victims When a burst of inbound messages hits the followup queue cap while the head item is mid-delivery, applyQueueDropPolicy can select that same in-flight item as an overflow victim. With the default dropPolicy: "summarize", the in-flight item ends up recorded in the overflow summary as dropped even though it is still being delivered, producing a contradictory record where the same message is both answered and reported as unanswered-due-to-overflow. The fix introduces an optional `inFlight` Set parameter to applyQueueDropPolicy and drainNextQueueItem. The followup queue state now owns a shared inFlight set that is: - Populated by drainNextQueueItem during the await run(next) window - Populated by the collect-merge drain path for activeGroupItems - Passed to applyQueueDropPolicy in enqueueFollowupRun The drop policy now computes an effective queue length that excludes in-flight items, and skips them when selecting splice victims. Fixes openclaw#103246 Co-Authored-By: Claude Opus 4.7 <[email protected]>
steipete
force-pushed
the
fix/103246-queue-drop-inflight
branch
from
July 10, 2026 05:11
ae907e0 to
a557ff1
Compare
Contributor
|
Land-ready proof for
Provenance: the front-splice overflow rule dates to No known proof gaps. Thanks @tzy-17 for identifying and implementing the core identity-set direction. |
Contributor
|
Merged via squash.
|
github-actions Bot
pushed a commit
to Desicool/openclaw
that referenced
this pull request
Jul 10, 2026
…ms as overflow victims (openclaw#103284) * fix(queue): prevent applyQueueDropPolicy from selecting in-flight items as overflow victims When a burst of inbound messages hits the followup queue cap while the head item is mid-delivery, applyQueueDropPolicy can select that same in-flight item as an overflow victim. With the default dropPolicy: "summarize", the in-flight item ends up recorded in the overflow summary as dropped even though it is still being delivered, producing a contradictory record where the same message is both answered and reported as unanswered-due-to-overflow. The fix introduces an optional `inFlight` Set parameter to applyQueueDropPolicy and drainNextQueueItem. The followup queue state now owns a shared inFlight set that is: - Populated by drainNextQueueItem during the await run(next) window - Populated by the collect-merge drain path for activeGroupItems - Passed to applyQueueDropPolicy in enqueueFollowupRun The drop policy now computes an effective queue length that excludes in-flight items, and skips them when selecting splice victims. Fixes openclaw#103246 Co-Authored-By: Claude Opus 4.7 <[email protected]> * fix(queue): align pending depth with active deliveries --------- Co-authored-by: Claude Opus 4.7 <[email protected]> Co-authored-by: Peter Steinberger <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What Problem This Solves
While a followup is executing, its object stays in the shared queue array until delivery succeeds. Overflow eviction,
drop:newadmission, and reported queue depth previously treated that active object as pending work. Under a burst, the same message could therefore be delivered and also recorded as dropped; non-summary policies could complete its lifecycle before delivery finished.Closes #103246
Why This Change Was Made
The queue now owns one identity set for items currently being delivered. A shared intersection-based counter excludes only active identities that are still present in the queue array; this matters because collect admission can remove active group items before the awaited delivery settles. Old and summarize policies skip those identities when selecting victims,
drop:newuses the same pending count before lifecycle publication, and public queue depth reports the same population.Single-item removal remains by reference and still happens only after successful delivery, preserving the retry and concurrent-mutation fix from #91450. Collect groups receive the same protection for their full awaited delivery window.
User Impact
drop:newadmits up to the configured number of genuinely pending messages while another message is active.Evidence
a557ff132ef88b144315ea5ccb25c5c8f2e67341.cbx_76d796ba2956, public networking, no Tailscale, no IAM instance profile:run_0e5b047f644f: 31/31 tests passed acrossqueue-helpers.test.ts, the production-ownerqueue.in-flight.test.ts, andreply-flow.test.ts.run_a4b0461ad81c:pnpm check:changedpassed the core/coreTests lanes, production and test tsgo checks, changed-file lint, and repository guards.29070791862passed on the exact head, including build artifacts, lint, production/test types, and all Node shards (11,628 passed, 3 skipped in the full Node lane).Co-Authored-By: Claude Opus 4.7 [email protected]