timescale.info
Sign inSign up

How OpenChronology was built

Every merged pull request of openchronology/timeline-app, its first week of commits and its releases; and before them the 2020 PureScript editor, from snapshots of its deleted repositories in the Wayback Machine. Written to this server through the HTTP API.

327 moments · 2020-03-09T00:15:08Z CE – 2026-11-02T20:11:21Z CE · by @athan · @athan

#288 · The next-postgres test holds a preparing copy's mark while it checks it

  • timeline-app
  • pull request

Closes #280. **Cause:** not a server bug. The test simulates a copy still being prepared by setting the fork's `preparing_revision_id` itself. A request that `store.access` refuses with 409 for such a copy starts preparing it again in the background (`void this.prepare(id)`, \`server/store.mjs\`). Here that request is the `/history` page's, which redirects with 307. This retry is deliberate: it recovers a preparation that skipped a locked copy (#193). The fork is small, so the retry rebuilt it and cleared the mark within milliseconds. Whichever of the following checks ran after that saw a ready copy, which is why `/document` sometimes answered 200 instead of 409. The background job only clears a mark on a row it found marked and locked itself, so nothing clears a mark it didn't see. **Fix (test only):** after committing the mark, the test holds the fork's row with `SELECT … FOR UPDATE` in its own transaction while it runs the "preparing" checks. The retry's `FOR UPDATE SKIP LOCKED` then skips the copy. None of those request paths lock the row, so they don't wait. The lock is released in a `finally`, so a failed check can't leave the pool unable to end, as in #238. **Evidence:** - **Reproduction:** with a 3 s pause added after the `/history` request, the old test failed every time, at `preparing` false !== true. With the lock and the same pause, it passed. - **Under load:** 12 of 12 runs of the fixed test passed with 6 busy CPU processes. An earlier loop of 10 had 8 passes. Its 2 failures were the guest copy rate limit (429 "Too many copies"), whose per-minute window is stored in the database across back-to-back runs. CI starts each run on a fresh database. The second loop cleared `oc_auth_attempts` between runs. - **Unit tests:** `npm test` passes 306 of 306, and Prettier is clean.

Sources

Open #288 · The next-postgres test holds a preparing copy's mark while it checks it in the timeline