Skip to content

fix(queue/mysql): make Insert idempotent on (topic, partition_key, id)#163

Merged
behinddwalls merged 1 commit into
mainfrom
sergeyb/mysql-queue-idempotent-publish
May 28, 2026
Merged

fix(queue/mysql): make Insert idempotent on (topic, partition_key, id)#163
behinddwalls merged 1 commit into
mainfrom
sergeyb/mysql-queue-idempotent-publish

Conversation

@sbalabanov
Copy link
Copy Markdown
Contributor

Summary

  • queue_messages schema documents its UNIQUE KEY (topic, partition_key, id) as supporting "INSERT ... ON DUPLICATE KEY to enforce idempotent publishes", but message_store.Insert issued a plain INSERT that surfaced 1062 duplicate-key errors on repeated publishes — pushing dedup responsibility onto every caller that the schema already promised to absorb.
  • Add ON DUPLICATE KEY UPDATE topic = topic so retried publishes succeed silently and the first message remains authoritative (the no-op write does not mutate payload, metadata, or created_at).
  • Realign TestIdempotentPublish, which previously locked in the schema/code mismatch by asserting the second publish errored; add a sqlmock unit test covering the same behavior.

Test plan

  • go test -count=1 ./extension/queue/mysql/... passes (unit + sqlmock).
  • make integration-test-extensions (covers TestIdempotentPublish against real MySQL).
  • CI green on the PR.

🤖 Generated with Claude Code

The queue_messages schema documents its UNIQUE KEY as supporting
"INSERT ... ON DUPLICATE KEY to enforce idempotent publishes", but
message_store.Insert used a plain INSERT that surfaced 1062
duplicate-key errors to the caller on a repeated publish. That made
publishers responsible for deduplication the schema was already
designed to absorb, and turned legitimate retries (network blip,
caller-side retry loop, user clicking a button twice) into hard
errors.

Add `ON DUPLICATE KEY UPDATE topic = topic` so:

- duplicate publishes for the same (topic, partition_key, id) succeed
  silently, and
- the existing row is preserved unchanged — the no-op write does not
  overwrite payload, metadata, or created_at, so the first publish
  remains authoritative.

The integration test TestIdempotentPublish previously asserted that
the second publish errored — i.e. it locked in the schema/code
mismatch. Realigned to assert the documented contract: the second
publish must succeed silently. Added a sqlmock-based unit test for
the same behavior.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@sbalabanov sbalabanov requested review from a team and behinddwalls as code owners May 28, 2026 22:24
@behinddwalls behinddwalls added this pull request to the merge queue May 28, 2026
Merged via the queue into main with commit 5f690a7 May 28, 2026
13 checks passed
@github-actions github-actions Bot deleted the sergeyb/mysql-queue-idempotent-publish branch May 28, 2026 22:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants