defer pruneCompletedChannelReqs until after onReadyToSend's index walk

Reviewer flagged that prune was mutating pendingMessagingRequests under
index iteration. Concrete failure: if prune drops the entry at the
current idx, the seq shifts and `idx.inc()` skips the next slot.

Hoist the single prune call to after the outer loop. Prune is idempotent
on the final-state filter, so doing it once at the end is equivalent to
calling it per-error-path while keeping idx aligned.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Ivan FB 2026-05-29 11:00:00 +02:00
parent 3f1a45c73c
commit 20c71c6929
No known key found for this signature in database
GPG Key ID: DF0C67A04C543270

View File

@ -220,7 +220,6 @@ proc onReadyToSend(
## parent `channelReqId` can still be pruned once its siblings
## are also final.
self.pendingMessagingRequests[idx].segmentSendState = SegmentSendState.Failed
self.pruneCompletedChannelReqs()
idx.inc()
continue
let wireBytes = seq[byte](encrypted)
@ -254,7 +253,6 @@ proc onReadyToSend(
),
)
self.pendingMessagingRequests[idx].segmentSendState = SegmentSendState.Failed
self.pruneCompletedChannelReqs()
idx.inc()
continue
@ -263,6 +261,10 @@ proc onReadyToSend(
self.requestIds.mgetOrPut(channelReqId, @[]).add(messagingReqId)
idx.inc()
## Prune once after the index walk completes. Calling it inside the
## loop would shift entries and misalign `idx` for the next iteration.
self.pruneCompletedChannelReqs()
proc send*(
self: ReliableChannel, payload: seq[byte], ephemeral: bool = false
): Result[RequestId, string] =