Skip to content

Replace failure groups only for the batch's newest attempt - #5694

Open
johnsimons wants to merge 1 commit into
masterfrom
john/review
Open

Replace failure groups only for the batch's newest attempt#5694
johnsimons wants to merge 1 commit into
masterfrom
john/review

Conversation

@johnsimons

Copy link
Copy Markdown
Member

Ingestion replaces a message's failure group rows wholesale on every attempt, matching how the Raven persister assigns FailureGroups, so a message that fails again with a different exception moves to the group its latest attempt was classified into.

The upsert only lets an attempt supply the payload columns when it is at least as new as the stored one, but the group replacement had no such guard. An older attempt arriving late from a concurrent writer therefore left the row describing one failure and the group rows describing another. Group replacement now applies only to the messages the batch is the newest attempt for, established by reading back the stored LastAttemptedAt inside the batch transaction, where the upsert already holds a row lock on every message involved.

The read back compares with <= rather than ==, because PostgreSQL stores timestamps at microsecond precision while DateTime has 100ns ticks. Truncation is monotonic and applies to both sides of the upsert's own guard, so the two stay in step at any column precision.

Ingestion replaces a message's failure group rows wholesale on every
attempt, matching how the Raven persister assigns FailureGroups, so a
message that fails again with a different exception moves to the group
its latest attempt was classified into.

The upsert only lets an attempt supply the payload columns when it is
at least as new as the stored one, but the group replacement had no
such guard. An older attempt arriving late from a concurrent writer
therefore left the row describing one failure and the group rows
describing another. Group replacement now applies only to the messages
the batch is the newest attempt for, established by reading back the
stored LastAttemptedAt inside the batch transaction, where the upsert
already holds a row lock on every message involved.

The read back compares with <= rather than ==, because PostgreSQL
stores timestamps at microsecond precision while DateTime has 100ns
ticks. Truncation is monotonic and applies to both sides of the
upsert's own guard, so the two stay in step at any column precision.
@johnsimons johnsimons self-assigned this Aug 4, 2026
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.

1 participant