Fix UNIQUE constraint violation on messages table when resuming conversations#74
Closed
olsonjeffery wants to merge 4 commits into
Closed
Fix UNIQUE constraint violation on messages table when resuming conversations#74olsonjeffery wants to merge 4 commits into
olsonjeffery wants to merge 4 commits into
Conversation
…rsations - Add ReaderCancellation field and Notify-based cancellation to reader task in subscribe_and_spawn() - Cancel old reader task and event stream before creating new subscription in resume_turn - Remove next_seq() and inline atomic seq generation in persist_event() via SQL subquery - Add test_persist_event_concurrent unit test verifying unique seq under concurrency - Rebase onto current main (includes timestamp column additions)
…logic - Extract repeated reader+event cancellation pattern into - Remove unnecessary intermediate variable - Simplify inner block to direct let bindings - All 432 unit tests pass, cargo fmt/clippy clean
- Simplified map_sdk_event_to_provider_event by extracting duplicated chrono::Utc::now().naive_utc() to a local binding - Converted nested if/else in SessionStatus handling to early-return guard + match on status_type.as_str() - Extracted client_and_user_id() helper to deduplicate lock-then-clone pattern in start_turn and resume_turn - Added test_provider() test helper to reduce struct construction dup - Fixed pre-existing clippy warnings: bool_assert_comparison, len_zero, needless_borrows_for_generic_args, single_match, needless_borrow
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.
Summary
Fixes a
UNIQUE constraint failed: messages.project_key, messages.session_id, messages.seqerror that occurs when resuming a conversation (sending a follow-up message). The conversation becomes inert — model response events fail to persist and the stream stalls.Root Causes
RC1: Reader task ignores cancellation signal — In
subscribe_and_spawn(), the event reader task is spawned without receiving the cancellation handle. Whenresume_turn()cancels the old subscription and creates a new one, the old reader task keeps running. Both reader tasks then callpersist_event()for the same session, producing duplicateseqvalues.RC2: next_seq() is not atomic —
next_seq()performs a separateSELECT MAX(seq)beforeINSERT, making concurrent calls from overlapping reader tasks produce the same seq value.Changes
Phase 1: Pass cancellation handle to reader task
ReaderCancellationusingArc<tokio::sync::Notify>for per-task cancellation independent of the SDK subscription handlereader_cancellation.notified()branch to the reader task'stokio::select!loopcancel_inflight()helper to deduplicate cancellation logic acrossresume_turn(),abort_turn(), andshutdown()Phase 2: Make seq generation atomic
next_seq()function entirelyINSERT INTO messages ... VALUESstatementRefinements
Testing
test_persist_event_concurrentunit test validates 20 concurrent calls produce unique monotonic seq values