sandboxd: workspace filecache — cross-node NAS-backed workspace sync - #71
Closed
doge-rgb wants to merge 1 commit into
Closed
sandboxd: workspace filecache — cross-node NAS-backed workspace sync#71doge-rgb wants to merge 1 commit into
doge-rgb wants to merge 1 commit into
Conversation
Bind a claimed sandbox to a shared workspace on a NAS mount and keep the two in sync under a multi-writer, close-to-open contract, so a sandbox works against a local disk (no network client, no FUSE in the guest) while its workspace is durable and visible to other sandboxes on other nodes. Why: sandboxes need a persistent, shareable working directory, but a NAS mounted into the guest pays a synchronous round trip per metadata op — ~1.4-2ms on EFS, ~100x a local disk, so an unpack of 100k files runs minutes instead of seconds. Staging the working set on a node-local disk and syncing deltas to the NAS out of band keeps guest I/O at local latency and moves the NAS cost off the hot path. Design: - new filecache package: the sync engine. The guest workspace is the source of truth during a session; a per-node writer publishes its delta to <root>/<workspace> plus an append-only journal, and pulls other writers' journal entries. The NAS itself is the rendezvous — pullers poll a seq file and fetch only named deltas, no central coordinator. Concurrent edits resolve last-writer-wins with the loser preserved as a .fc-conflict copy; deletes propagate via journal tombstones. - pool.Manager arms a session on claim (beside egress) and runs a barrier on release/reap that publishes the final delta before teardown, so the next open sees it through the NAS's own close-to-open semantics. - dedicated-disk mode (opt-in) puts the workspace on a fresh read-write ext4 virtio-blk disk, reusing the operator-volume disk-attach and by-serial device discovery, isolating it from the guest rootfs COW. - claim carries an optional workspace name (SDK WithWorkspace); nodes with no workspace root ignore it, so the field is safe for older nodes. Feature is off unless workspace_root is configured. The workspace NAS mount should use a low attribute cache (actimeo=1) so cross-node journal changes appear within the visibility budget.
doge-rgb
force-pushed
the
filecache-integration
branch
from
August 12, 2026 17:05
57fe194 to
9d87d9f
Compare
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.
What
Bind a claimed sandbox to a shared workspace on a NAS mount and keep the two in sync under a multi-writer, close-to-open contract. A sandbox works against a node-local disk — no network client, no FUSE in the guest — while its workspace is durable and visible to other sandboxes on other nodes.
Feature is off unless
workspace_rootis configured; a claim opts in with an optional workspace name (WithWorkspace), ignored by nodes that don't have it.Why
Mounting a NAS (EFS over NFSv4.1) into the data path pays a synchronous round trip per metadata op. Measured from a pool node:
The metadata path is ~100x a local disk (network RTT is only 0.18 ms — the rest is server-side), same-directory writes serialize server-side, and no mount option moves it. Staging the working set on a node-local disk and syncing deltas to the NAS off the hot path keeps guest I/O at local latency.
With the filecache (measured inside a real sandbox)
Same 100k-file / 565 MB workload, run in a claimed sandbox on this branch (guest-local virtio-blk storage, dedicated workspace disk attached):
The guest pays local-disk latency for every operation; the NAS sees batched deltas on the sync cadence and a final barrier at release.
Design
filecachepackage — the sync engine. During a session the guest workspace is the source of truth; a per-node writer publishes its delta to<root>/<workspace>plus an append-only journal, and pulls other writers' entries. The NAS itself is the rendezvous — pullers poll aseqfile and fetch only named deltas, no central coordinator. Concurrent edits resolve last-writer-wins with the loser preserved as<path>.fc-conflict-<ts>; deletes propagate via journal tombstones.pool.Managerarms a session on claim (beside egress) and runs a barrier on release/reap that publishes the final delta before teardown, so the next open sees it through the NAS's own close-to-open semantics.workspace_disk_mb) puts the workspace on a fresh read-write ext4 virtio-blk disk, built on the writable catalog-volume primitives from Writable catalog volumes with a guest filesystem shutdown lifecycle #72 (DiskAttachwith a rw spec,MountVolumerw,UnmountVolume; by-serial discovery from sandboxd: add read-only catalog volumes #69), isolating it from the guest rootfs COW./workspaceshows up as a real/dev/vdXmount. Unlike a catalog volume — one persistent node-local image, single writer by admission — the workspace disk is per-sandbox scratch: the durable artifact is the NAS workspace, which any number of sandboxes on any node share through the sync plane.WithWorkspace/WithNoRedirect.Verified on a 2-node cluster (real EFS filesystem)
Rebased onto #72 and re-verified on both nodes: full unit suite (with
-race), dual-GOOS lint clean, and the cross-node E2E below re-run green on the rebased binary (propagation 7 s / 13 s / 9 s, barrier and dedicated-disk mount confirmed).Cross-node E2E (sandboxd-driven, no external agent), FAILS=0:
.fc-conflictcopy on both nodesLoad (10 workspace-pairs = 20 sandboxes with dedicated disks, all syncing concurrently):
Unit tests cover the journal round-trip, tar hydrate/publish, atomic overwrite, and name parsing (
sandboxd/filecache/sync_test.go). Full suite green (14 sandboxd packages + SDK).Deployment note
The workspace NAS mount must use a low attribute cache (
actimeo=1). With the commonactimeo=3we measured cross-clientreaddirlatency of ~8 s (negative-lookup ~21 s) on EFS, which pushes visibility to the edge of the SLA;actimeo=1drops it to ~1 s.Follow-ups (not in this PR)
cocoon-sandbox-operator) annotation →workspacepassthrough for the K8s Sandbox CRD.