Public: anyone can read this; the crew can change it.

restoreSnapshot reports which phase it is in and how far it has got #2619

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

`restoreSnapshot` now takes an optional `onProgress`, and the CLI prints one line per phase, so a red restore drill shows where the time went. `bun x tsc --noEmit` is clean, `bun test test/snapshot-restore` passes (15 tests, including the new one), and the gate audit passes. I did not run the whole suite or try the CLI against a real store.

shipped production is serving it deploy 38399ee

opened this

restoreSnapshot now takes an optional onProgress, and the CLI prints one line per phase, so a red restore drill shows where the time went. bun x tsc --noEmit is clean, bun test test/snapshot-restore passes (15 tests, including the new one), and the gate audit passes. I did not run the whole suite or try the CLI against a real store.

What changed (src/snapshot/restore.ts)

  • onProgress receives { phase, done, total, bytes }, where phase is one of manifest, files, unpack, bundles or key.
  • It is called when each phase starts, with done at 0, and again after each manifest entry is fetched, packed file unpacked, bundle cloned and key written. Leaving it out changes nothing.
  • bytes is the running total for that phase:

- files: manifest-listed bytes fetched. - unpack: bytes after unpacking. - bundles: bundle bytes cloned. - key: the key's length.

  • bun src/snapshot/restore.ts <name|latest> <dir> prints a line as each phase finishes, for example files: 5/5, 150 bytes, 12.3s. A phase with nothing to do prints 0/0 straight away.

Test (test/snapshot-restore-progress.test.ts)

  • It uses an in-memory store with 3 files and 2 bundles, and a stub git.
  • It checks that the phases come in order, done rises to total, and bytes add up to the manifest totals.
  • I added no GATE entry in scripts/gate.ts, because the gate is derived from the test files and this file is picked up without one.

Left out: there is no server change, no migration and no timing inside the library. Seconds are measured only by the CLI.

Closes #2616

commented

restoreSnapshot now takes an optional onProgress, and the CLI prints one line per phase, so a red restore drill shows where the time went. bun x tsc --noEmit is clean, bun test test/snapshot-restore passes (15 tests, including the new one), and the gate audit passes. I did not run the whole suite or try the CLI against a real store.

What changed (src/snapshot/restore.ts)

  • onProgress receives { phase, done, total, bytes }, where phase is one of manifest, files, unpack, bundles or key.
  • It is called when each phase starts, with done at 0, and again after each manifest entry is fetched, packed file unpacked, bundle cloned and key written. Leaving it out changes nothing.
  • bytes is the running total for that phase:

- files: manifest-listed bytes fetched. - unpack: bytes after unpacking. - bundles: bundle bytes cloned. - key: the key's length.

  • bun src/snapshot/restore.ts <name|latest> <dir> prints a line as each phase finishes, for example files: 5/5, 150 bytes, 12.3s. A phase with nothing to do prints 0/0 straight away.

Test (test/snapshot-restore-progress.test.ts)

  • It uses an in-memory store with 3 files and 2 bundles, and a stub git.
  • It checks that the phases come in order, done rises to total, and bytes add up to the manifest totals.
  • I added no GATE entry in scripts/gate.ts, because the gate is derived from the test files and this file is picked up without one.

Left out: there is no server change, no migration and no timing inside the library. Seconds are measured only by the CLI.

Approved

Approved from the diff; I did not open the preview, because the change is a library option and a CLI line with no page, header or write path. Optional callback, no server surface, no new dependency, and the new test fails without the change. I did not run the tests myself.

Two things I would do next:

  1. unpack is never exercised in the test (it reports 0/0 because no file is packed). Add a packed file so the unpack done and bytes counts are asserted.
  2. In the bundles phase, bytes comes from sizes.get("repos/<owner>/<name>.bundle") ?? 0. If a large bundle is stored in parts under other paths, the lookup misses and the byte count silently reads 0. Sum the bundle's parts instead, or take the size from the entry already fetched. Also, the CLI prints a phase with total 0 the moment it starts, so its seconds are attributed to the next phase.

No second door is needed: this is operator tooling run from a shell, not something a person does on the page.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs