Prufy notes
Types and data ยท 12 min

Things happening at once

Most bugs here only appear when two things overlap. So the design leans on the database, where the rules hold no matter how requests interleave.

You can't reason about this by reading one function, because the bug lives between two of them. So step through these frame by frame, and watch the middle column.

Frame by framePick a race and step through it
Account A's check
The database
Account A's claimpending
Account B's claimpending
Owner index
Empty
Account B's check

Both accounts have a pending claim on example.com, and both have published a valid record. Their checks finish at the same moment.

Step 1 of 6
At no instant are there two owners. The index is what decides, and it can't be raced past.
Predict it first
Two accounts tie. A wins, and B stays pending. B's record is still valid. What happens on B's next check?

Three tools, three jobs

ToolProtects against
Row lockTwo writers inside the database at the same moment
Version and expectedVersionA decision based on something read earlier, like a stale screen
Unique indexBreaking the rule itself, whatever the code does
LeaseAnother worker starting the same slow job, after the locks have gone

How this is actually tested

These run on real Postgres, with up to 12 connections, because the behaviour only exists when separate transactions overlap.

TestWhy it's convincing
Two accounts verify, 25 roundsAsserts exactly one owner, every round
Second writer blocks, then losesDeterministic: holds a transaction open and confirms the other hasn't finished
First rolls back, waiter winsThe other branch of the same mechanism
A locked row is skippedWithout SKIP LOCKED, it hangs and times out. This was tried
8 workers over 40 claimsNone leased twice, all leased
10 transitions at onceThe count ends at exactly 10
One token consumed by 8 callersExactly one gets it