fix(project-files): requeue rendered-artifact search after commit and trim Project read transactions
Merged
WA
3d ago+574+574+012345678901234567890123456789-310-310-012345678901234567890123456789
Summary
All changes are on flag-gated Project file paths (behind the projects rollout) plus small shared helpers whose workspace behavior is unchanged.
- Lock upgrade in Project artifact reads.
readArtifactholds the Project lock and the source row shared, but its final transaction calledmarkFileSearchArtifactReadyInTx, which takes the Project lock exclusively and file rowsFOR UPDATE. Every compiled render did this (a cache hit still returnsartifactKey), so concurrent generated-document reads in one Project could deadlock or wait out the 5 s Project lock timeout. The read now records the search completion and requeues after commit viarequeueFileSearchForRenderedArtifact(lock-free current check, then its own transaction). That transaction now takes the owner lock under the 1 s artifact-ready bound instead of the 5 s Project lock bound; a timeout is caught and logged and never fails the read. - Fewer authorized transactions. Artifact, inline, and CSV preview reads authorize from their own snapshots (
prepareFromSnapshot) instead of a separate preflight. Artifact inputs are snapshotted and admitted only when the source references any; the final transaction still rechecks the source, every input, and provenance after storage reads. Artifact: 4 transactions / 3 admissions → 2 / 2 without inputs, 3 / 3 with. Inline and CSV: 3 → 2. Search: drops the nestedlistProjectFileFoldersuse case. - Artifact inputs. Downloads run with bounded concurrency after checking declared sizes against the per-file and total budgets. Each read is capped at its declared size plus the unclaimed budget, and the first failure aborts the rest. The request signal now reaches render, downloads, and compile.
- Project inline delivery streams instead of buffering. It fences the file head after storage opens and serves
workspaceFileCacheControl(contentAddressed)like workspace inline. It no longer lists every Project folder. - Project search admits, withholds stale previews, and reports provenance after its snapshot commits.
loadFileSearchDeliveryreturns an explicitcurrentset, and provenance is classified only when a content gate or delivery observer needs it. - Foreign page embeds. A Project page that embeds another owner's image now fails as a missing input (
not_found) instead of a 500, through a typedProjectPageForeignEmbedError. - Cleanup.
- Page inline limits are exported from
page-document.server.tsand reused. knip.jsoncnarrows theproject-files.tsentry totypes.SearchProjectFileContentInputis un-exported.- The CI isolate build step uses
paths: ["."]andJOBS=4, matchingdocker/app.Dockerfile.
- Page inline limits are exported from
Expected rebase conflicts in the open Project file stack:
- #9018: none expected.
- #9019 and #9034 (still based on pre-squash #9017): conflicts in
artifacts.ts,previews.ts,search.ts,artifact-ready.ts,delivery.ts, andchecks.yml; take staging's side.- The #9034 inline route must present the new stream result (
stream,contentLength,contentAddressed). readProjectFileArtifactkeepsfile.folderPathfor its VFS paths.
- The #9034 inline route must present the new stream result (
Type of Change
- Bug fix
Testing
- Biome on all changed files;
lib/workspace-files/page-compile.test.ts. - New integration checks in
content-rendered.integration.ts:- A generated artifact read beside a concurrent shared Project holder completes and requeues search. On the previous code it times out on the exclusive Project lock.
- A contended requeue gives up within its short bound without failing the read.
- A Project page embedding another owner's image is
not_found.
- Type-check, audits, and integration suites run in CI.
Checklist
- Code follows project style guidelines
- Self-reviewed my changes
- Tests added/updated and passing (new tests pass the
test-auditauthoring gate) - No new warnings introduced
- I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)