fix(plugins): skip stale outbox claims so a reply is not posted twice #768

Open
dries wants to merge 1 commit from fix/conversation-stale-claim into main
Owner

Summary

  • pumpConversationOutbox claims rows without a lease. A pump that reads a row before a concurrent delivery acknowledges it can still pass the in-flight check after that delivery finishes, so it posts the reply a second time.
  • deliverConversationReply now re-checks before sending that the row is still pending, due, and has the same attempt count (PluginConversationReplyCurrent). A real at-least-once replay (acknowledgment lost) still happens, because that row stays pending.
  • This made TestConversationUnavailableOutcomeReachesThread flaky in CI ("redelivery produced 2 unavailable notices"), for example on PR #755.

Testing

  • New TestConversationStaleClaimIsNotResent: it failed before the fix (reply posted twice) and passes after it.
  • go test ./internal/server ./internal/state, go vet, and golangci-lint pass.
## Summary - `pumpConversationOutbox` claims rows without a lease. A pump that reads a row before a concurrent delivery acknowledges it can still pass the in-flight check after that delivery finishes, so it posts the reply a second time. - `deliverConversationReply` now re-checks before sending that the row is still pending, due, and has the same attempt count (`PluginConversationReplyCurrent`). A real at-least-once replay (acknowledgment lost) still happens, because that row stays pending. - This made `TestConversationUnavailableOutcomeReachesThread` flaky in CI ("redelivery produced 2 unavailable notices"), for example on PR #755. ## Testing - New `TestConversationStaleClaimIsNotResent`: it failed before the fix (reply posted twice) and passes after it. - `go test ./internal/server ./internal/state`, `go vet`, and `golangci-lint` pass.
fix(plugins): skip stale outbox claims so a reply is not posted twice
Some checks failed
CI / Frontend (pull_request) Failing after 3m27s
CI / Playwright E2E (pull_request) Failing after 3m27s
CI / Backend (pull_request) Successful in 14m6s
CI / Semantic Tag (pull_request) Has been skipped
CI / Coverage Results (pull_request) Failing after 17s
47f5fc193a
dries force-pushed fix/conversation-stale-claim from 47f5fc193a
Some checks failed
CI / Frontend (pull_request) Failing after 3m27s
CI / Playwright E2E (pull_request) Failing after 3m27s
CI / Backend (pull_request) Successful in 14m6s
CI / Semantic Tag (pull_request) Has been skipped
CI / Coverage Results (pull_request) Failing after 17s
to da4feed4ca
Some checks are pending
CI / Backend (pull_request) Successful in 8m47s
CI / Frontend (pull_request) Successful in 12m23s
CI / Coverage Results (pull_request) Waiting to run
CI / Playwright E2E (pull_request) Successful in 12m11s
CI / Semantic Tag (pull_request) Waiting to run
2026-09-29 10:53:35 +02:00
Compare
Some checks are pending
CI / Backend (pull_request) Successful in 8m47s
Required
Details
CI / Frontend (pull_request) Successful in 12m23s
Required
Details
CI / Coverage Results (pull_request) Waiting to run
Required
Details
CI / Playwright E2E (pull_request) Successful in 12m11s
Required
Details
CI / Semantic Tag (pull_request) Waiting to run
Required
Details
Some required checks are missing.
The changes on this branch are already on the target branch. This will be an empty commit.
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin fix/conversation-stale-claim:fix/conversation-stale-claim
git switch fix/conversation-stale-claim
Sign in to join this conversation.
No description provided.