Repository navigation
feat(sandbox): resilient image downloads with progress and cancel - #208
Merged
Merged
Conversation
…ials The storage host cuts long transfers at arbitrary points, so the multi-hundred-MB image download used to die with undici's "TypeError: terminated" and start over on every create attempt, leaking an orphaned partial-<uuid> file each time. stageAsset now stages in-flight downloads content-addressed at <cacheDir>/<sha256>.partial and resumes them with HTTP range requests, retrying until five consecutive attempts make no progress. The partial survives failures and aborts so the next create continues where the last one stopped; verification failures still delete it, and every run sweeps partials that belong to other digests, including the legacy partial-<uuid> orphans. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The Add sandbox dialog used to show only a static "Creating..." while
the multi-hundred-MB image downloaded, with Cancel disabled and no way
out but waiting or an error.
stageAsset now reports throttled {bytes, totalBytes} progress, threaded
through every provider's create/reset into the controller's job state,
so the dialog renders a progress bar with downloaded/total MB. A new
sandbox-cancel IPC channel aborts the in-flight job: a cancelled create
persists and starts nothing (previously an aborted create still
registered the sandbox), a cancelled reset stays stopped instead of
starting from a half-reset image, and the kept partial means the next
attempt resumes. The dialog body also gains the horizontal padding the
header and footer already had.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Creating a sandbox on an unstable connection fails with
Error invoking remote method 'sandbox-add': TypeError: terminated. The storage host cuts long transfers at arbitrary points, andstageAssethad no retry: the whole ~800 MB download restarted from zero on every Create click, and each failed attempt leaked an orphanedpartial-<uuid>file insandbox-images/(observed: 25 MB, 203 MB, and 673 MB orphans from three attempts). On top of that, the Add sandbox dialog gave no feedback beyond a spinner during the download, its Cancel button was disabled the whole time, and the dialog body had no horizontal padding.Download resume (commit 1)
<cacheDir>/<sha256>.partial; an interrupted download resumes viaRange: bytes=<offset>-(the storage host advertisesaccept-ranges: bytes), both across retries within one call and across separate Create attempts.partial-<uuid>orphans; verification failure still deletes the partial. Verification now hashes in a separate pass after download (required for resume).Progress + cancel UI (commit 2)
stageAssetreports throttled{bytes, totalBytes}progress (at most every 200 ms), threaded through every provider'screate/resetinto the controller's job state and over the existingsandbox-eventpush; the dialog renders a progress bar plus123/761 MB.sandbox-cancelIPC channel. A cancelled create resolves toundefined: nothing is persisted or started and the dialog stays open (previously an aborted create still registered the sandbox — fixed); a cancelled reset stays stopped instead of starting from a half-reset image. The kept partial means the next attempt resumes where the cancelled one stopped.px-4to match the 16 px padding the header and footer already had.Testing
image.test.ts: mid-stream cut → range resume, resume of a pre-existing partial, stall give-up preserving the partial, 416 restart, stale-partial sweep, progress reporting (initial 0, final total, monotonic).controller.test.ts: job progress events, cancel aborts + persists nothing, cancel for a different sandbox is a no-op.bun testandbun typecheckclean inpackages/codev-sandbox(84 tests) andpackages/app(657 tests);bun typecheckclean inpackages/desktopandpackages/ui.🤖 Generated with Claude Code