Prufy notes
Types and data ยท 7 min

Writing safely

A status change touches the claim and the audit log, and sometimes another account's claim too. It has to happen completely or not at all.

The one way a status changes

applyTransitionStep through it
Service
applyTransition
transition()
Postgres
Step 1 of 7
An event arrives
The service knows what happened, and asks for it to be applied. It has no say in what status comes out.
packages/db/src/queries/apply-transition.ts

In claim-service.ts the service reaches this through one small helper, move. It calls applyTransition, and if that succeeded it calls alerts.statusChanged with the status before and the claim after. The alert is asked for only after the transaction has committed, so a failed email can never roll a status change back. The Alerts chapter picks up from there.

Taking a name from another account

When a claim passes a check and someone else owns the name, this runs instead.

transferOwnershipStep through it
Service
transferOwnership
Old claim
New claim
Step 1 of 5
Take the locks consistently
Always locking in the same order means two concurrent transfers can't deadlock.
packages/db/src/queries/transfer-ownership.ts

Why a check is three separate writes

A check takes up to 8 seconds of network time. A transaction holds a database connection and possibly locks the whole while, so a check is split around the slow part.

startCheck
Commit
Ask DNS: up to 8 seconds
No transaction open
finishCheck
Commit
applyTransition
Commit

If the process dies

Every way of crashing has been thought about, and none needs a person to clean it up.

It diesWhat recovers itResult
Mid-transactionPostgres rolls it backNothing happened
After startCheck, before finishCheckThe next startCheck closes any check older than 60 secondsThe claim isn't blocked
While a worker holds a leaseThe lease expires after 60 secondsAnother worker picks it up