Repository navigation
feat: upload each cache key once, default the sandbox transport to rpc, and bake a prebuilt DuckDB into the Rust image - #235
Conversation
…lied restore A restore reports hit, miss or unapplied. An unapplied archive runs the miss path without a save; a save heads its key first and skips the pack and upload when the archive is stored. On a transport that cannot stream into the container, a restore reads only the head and logs the transport once per execution. Spec: specs/adr/0007-cost-efficient-execution.md (#232)
…describe the unapplied outcome The live cache tests cover an rpc restore with no stored archive (miss, pack, upload), an rpc restore whose tar xzf exits non-zero (unapplied, no save) and a websocket restore (head only). Comments and runs/README.md describe a restore off the rpc transport as unapplied rather than a miss, and the transport log as once per Layer instance. Spec: specs/adr/0007-cost-efficient-execution.md (#232)
There was a problem hiding this comment.
AI code review — 💬 Comment
Risk tier: full · 0 critical · 1 warnings · 0 suggestions
Reviewers: security
1. ⚠️ Warning — Concurrent cache misses still duplicate packing and uploads
📍 packages/runtime-cf/src/cache-restore-or.ts:48-63
'composeSave' performs a non-atomic 'exists' check followed by 'pack'. Parallel executions can all observe a missing key, then each run the expensive tar creation and upload, contradicting the stated upload-once behavior and potentially causing substantial duplicate CPU, I/O, and R2 traffic. Add per-key coordination/locking or use an atomic create-if-absent mechanism before packing/uploading.
…olved transport onto every container resolveSandboxTransport takes the CONFIG_KV sandbox.transport:<repo> pin, else the Worker-wide SANDBOX_TRANSPORT var, else rpc, skipping a value that is not a transport name at either level. The runtime pins the result onto every container it acquires and hands it to the R2 cache, so a restore streams an archive in unless a repo or the Worker opts back to http.
… the Rust sandbox variant
…LIB_DIR's precedence
…ves no member without its dependencies
There was a problem hiding this comment.
AI code review — 🛑 Request changes
Risk tier: full · 1 critical · 2 warnings · 1 suggestions
Reviewers: security 0 · performance 2 · code-quality 0 · documentation 1 · release-management 0 · compliance 2 · agents-md 0
1. ⚠️ Warning — Every pnpm cache restore performs another install
📍 packages/core/src/primitives/install-cached.ts:154-163
The new 'relink' command runs after every restore, including cache hits and cache misses. 'pnpm install --frozen-lockfile --prefer-offline' still performs dependency resolution and filesystem work, and on a miss it repeats the install that 'onMiss' already performed. This adds avoidable latency to every pnpm run and can negate the cache benefit; use a narrowly scoped relink operation or only run it on hits when the archived tree actually requires workspace links.
2. ⚠️ Warning — Concurrent misses can still pack and upload the same cache key
📍 packages/runtime-cf/src/cache-restore-or.ts:51-63
The 'exists' check and 'pack' call are separate, non-atomic operations. Parallel executions can both observe a missing key, independently run the expensive archive creation, and upload duplicate archives, despite the comment promising upload-once behavior. Add per-key coordination or an atomic/conditional creation mechanism before packing, or accept and document the duplicate-work behavior.
3. 💡 Suggestion — Clarify that rpc is only the default transport
The opening sentence says containers run on the SDK's 'rpc' transport, but the documented configuration can resolve them to 'http' or 'websocket' via the repo pin or 'SANDBOX_TRANSPORT'. Reword this to say containers default to 'rpc' and use the resolved transport according to the precedence below, so readers are not given an unconditional claim that contradicts the configuration instructions.
4. 🛑 Critical — DuckDB license files are omitted from the distributed image
📍 infra/Dockerfile.sandbox-demo:171-172
The image copies only 'libduckdb.so' and three headers from the DuckDB release archive; no DuckDB license or copyright notice is retained. Since this adds and distributes DuckDB binaries/headers, preserve the applicable license notices in the image or another distributed compliance location.
There was a problem hiding this comment.
AI code review — 💬 Comment
Risk tier: full · 0 critical · 2 warnings · 0 suggestions
Reviewers: security
1. ⚠️ Warning — Concurrent cache misses still duplicate packing and uploads
📍 packages/runtime-cf/src/cache-restore-or.ts:52-64
The existence check and pack are not atomic: concurrent executions can all observe 'exists=false', then each run 'pack(opts)' and upload the same content. This defeats the stated upload-once optimization and can multiply tar/stream/upload CPU, container time, and R2 bandwidth under fan-out. Add per-key coordination or an atomic conditional-write/claim mechanism before packing.
2. ⚠️ Warning — Every cached install now starts a second pnpm install
📍 packages/core/src/primitives/install-cached.ts:156-164
The relink command runs unconditionally after 'restoreOr', including cache misses where 'onMiss' has already performed the full pnpm install and populated workspace links. This adds a pnpm startup and workspace/lockfile scan to every miss, and a potentially expensive install check to every hit. Restrict relinking to successful cache restores, or use a purpose-built link-only operation that cannot re-resolve or reinstall dependencies.
Containers run on the
rpctransport by default, the R2 cache uploads each content-addressed key once and skips the save on a restore it cannot apply, and the Rust sandbox variant ships a sha256-pinned prebuilt DuckDB shared library.rpc transport by default
resolveSandboxTransport(packages/runtime-cf/src/sandbox-transport.ts) resolves one transport per execution: theCONFIG_KVpinsandbox.transport:<repo>, else the Worker-wideSANDBOX_TRANSPORTvar, elserpc. A value that is not a transport name is skipped at its level.httpwithout a deploy.makeCFRuntimeLivepins the resolved transport onto every container the execution acquires (sandbox-cf.ts, once per container) and hands the same value to the cache Layer. A container keeps the transport it started with for its life.sandbox-transport.test.ts.runs/README.md§ Container transport documents the precedence, the rollback key and whyrpc.Upload each cache key once
RestoreFnreportshit,missorunapplied.composeRestoreOrrunsonMissonmissandunapplied, and saves only after amiss. A restore error still degrades to a miss.composeSaveheads the key before packing. A stored archive skipstar czfand the upload, so parallel misses on one key upload once. A failed head check packs as before.rpc. Onhttp/websocketit reads the key's head, reportsunappliedwithout downloading the body, and logs the transport once per execution. Anrpcapply that fails cancels the unread body and reportsunapplied.contextful-gateparts keepinstall: true, and a comment records why: the stage runs the consumer'scontextful-ci, and the consumer's.cargo/config.tomlcan setnet.offline, so nothing in this repo shows that the stage fetches its own crates.Prebuilt DuckDB in the Rust sandbox variant
WITH_RUSTvariant ofinfra/Dockerfile.sandbox-demo(RunSandbox) ships DuckDB's prebuiltlibduckdb.soand headers under/opt/duckdb, so a consumer that links DuckDB skips the C++ compile that dominates a coldcargo test.ARG DUCKDB_VERSIONpins the release; thelibduckdb-linux-amd64.zipasset is verified withsha256sum -cagainst the digest GitHub publishes for it. Other architectures fail the build.DUCKDB_LIB_DIR/DUCKDB_INCLUDE_DIRare exported, and an/etc/ld.so.conf.d/duckdb.confentry puts the library on the loader path for every exec user. The build assertsldconfig -presolveslibduckdb.so.bundled) build, and in a linked Linux buildDUCKDB_LIB_DIRtakes precedence overDUCKDB_DOWNLOAD_LIB=1. The consumer opt-in is documented on the layer and in the RunSandbox comment inwrangler.jsonc.WITH_RUSTvariant rather than the lean image the ADR names: RunSandbox is the only class with a Rust toolchain to build a linked consumer, andinfra/Dockerfile.sandboxsetsWITH_RUSTfor no class.Spec:
specs/adr/0007-cost-efficient-execution.md§ Upload each cache key once, § Fan-out parts install nothing their stage repeats (thecontextful-gateparts keepinstall: true, as above) and § Prebuilt heavy native dependencies in the image;specs/adr/0008-cheaper-waiting-and-transport.md§ rpc transport by default (#232). ADR-0007 § Dispatch only work is #234.Testing:
pnpm lint,pnpm typecheckandpnpm test(207 files, 2836 passed, 1 skipped) pass.sandbox-transport.test.tscovers the default, the var, the pin in both directions and skipped values.cache-r2-live.test.tsruns the live cache closures against a mockedgetSandboxand a fake bucket (http, websocket and rpc restores, an rpc miss, an rpcwriteFileortar xzffailure, a save of a stored key);cache-r2.test.tscoversunappliedandcomposeSave. Not run: an image build of the DuckDB layer and a linkedcargo buildagainst it; no PR CI builds images.