8 min read

Eye Training · Shared State and Races

Every await is a door. While your code waits, someone else walks through it and changes what you read.

Part 2 · Surface 18. Bug counts are hidden and some snippets are clean. See Start Here for how to use these drills.


J · The basics

Bug hunt
J · Cart endpoint
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min
Bug hunt
J · Like a post
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min
Bug hunt
J · Place order button
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min
Bug hunt
J · Register
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min

M · Three years in, these should jump out

Bug hunt
M · Search as you type
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min
Bug hunt
M · Reserve stock
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 2 min
Bug hunt
M · Redeem a coupon
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min
Bug hunt
M · Nightly report
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min
Bug hunt
M · API client
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 2 min
Bug hunt
M · Show details
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min

S · Where seniors stand out

Bug hunt
S · Refresh the token
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 2 min
Bug hunt
S · Refresh, done right
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 1 min
Bug hunt
S · Payment webhook
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 2 min
Bug hunt
S · Withdraw
Bug count hidden, and some snippets are clean. Click every line you think is wrong (or none), then check.
0:00 / 2 min

What your eye checks

Whenever code reads something, then awaits, then acts on what it read, ask:

  1. Who else could change it during the await? Another request, another tab, another instance, a retry.
  2. Is the check in the same atomic step as the write? A conditional UPDATE … WHERE, a unique constraint, SELECT … FOR UPDATE. A separate read is a gap.
  3. Is the arithmetic done by the database? likes = likes + 1, not post.likes + 1 written back.
  4. Where does this state live? A module variable is shared by every request; an in-process Set or lock exists once per instance.
  5. Is this a copy or a shared object? { ...obj } copies one level.
  6. Can it run twice? Double clicks, retries, webhook redelivery. Make it idempotent with keys and unique inserts.
  7. Which response wins? Out-of-order responses overwrite newer state unless you abort or check that the result is still wanted.
  8. Do concurrent callers each start the same work? Share one in-flight promise.

Tells

You seeAsk
let / const state at module level in a serverShared by whom?
find … await … update with a computed valueLost update?
if (exists) throw before an insertIs there a unique constraint?
A check, then a separate UPDATECan two requests pass the check?
An async submit handlerWhat about a double click?
await api… then renderIs the result still wanted?
A Set or flag used as a lockHow many processes?
{ ...defaults } then options.nested.x =Shared nested object?
if (expired) token = await refresh()How many callers refresh at once?
A webhook handler with side effectsWhat if it's delivered twice?
BEGIN, SELECT, then UPDATE … SET x = $1Is the row locked?

Go deeper