Skip to content

prerender-v0.13.0 — @harperfast/prerender

Choose a tag to compare

@harper-joseph harper-joseph released this 28 Jul 18:38
7a09629

Registry walks no longer hold pending writes across an open cursor.

Harper ends any transaction open past storage_maxTransactionOpenTime (default 30s), and the two outcomes are not equivalent — the discriminator is hasPendingWrites() at the moment the monitor fires:

  • pending writes → ABORTED and poisoned. Every later write or commit throws "Transaction was aborted after exceeding the open-transaction limit; split long-running work into smaller transactions" (422). Core deliberately refuses to force-commit a partial write set.
  • no pending writes → committed, clock reset, not poisoned. A read-only walk survives indefinitely.

So the dangerous shape is not "a long scan" but "a cursor still open while writes are pending" — and three loops were exactly that, each able to die partway through with rows already changed:

loop write issued inside the cursor
Sitemap.refresh prune RenderTarget.patch
Sitemap.delete RenderTarget.delete
RenderTarget.revalidate page patch + schedule put

All three are now two-phase — collect while reading, write once the cursor has closed — via a shared util/scan.js. This is the discipline util/reconcile.js already followed and documented.

A fourth exposure had nothing to do with cursors: the sitemap creation loop drained with await lastPromise, which awaits only the most recent write and left up to 49 others in flight, so writes still spanned a monitor tick despite looking drained. It now awaits the full batch.

Notes

  • collectFromScan caps what it buffers (config.scan.collectCap) but always scans to completion, so examined is the true registry size and truncated reports whether the caller acted on a partial set.
  • Yields on rows scanned, not rows collected: a walk that collects almost nothing is the healthy case, and awaiting a cursor drains microtasks without letting timers or I/O callbacks run.
  • New config.scan section: collectCap, batchSize, yieldEvery.
  • Recommended upgrade for any deployment with large sitemaps — this supersedes 0.12.0, which slightly lengthened the prune loop's exposure.

reconcileSchedules is unaffected: it walks read-only and is already two-phase, so it cannot reach the abort path.

Full detail: #43