mirror of
https://github.com/vercel/next.js.git
synced 2026-09-20 02:25:18 +08:00
228df5fd74
Backports the following to `next-16-3`, as a pair: - #96941 — "[turbopack] Retain fewer stale cache versions and use a TTL" (`ae1e53a`) - #97268 — "Add the mtime fallback back" (`52a3410`) The second fixes a bug in the first: #96941 changes the `CURRENT` file format from a bare big-endian `u32` to a JSON object, and an existing cache directory in the old format could no longer be aged. #97268 adds the mtime fallback so an unparsable `CURRENT` is aged by its mtime instead of failing. They only make sense together, hence one branch. Both cherry-picked with `-x`, no conflicts. Every touched source file is byte-identical to canary. ### Verification on this branch - `cargo check`, `cargo clippy --all-targets`, `cargo fmt --check` on `turbo-persistence` and `turbo-tasks-backend` — clean - `cargo test -p turbo-persistence -p turbo-tasks-backend` — all pass, 0 failures - includes the `db_versioning` tests, notably `test_unparsable_current_falls_back_to_mtime::case_1_old_u32_format` (the old-format compatibility case #97268 restores) - `cargo metadata --locked` — `Cargo.lock` consistent with the manifests, no lockfile update needed - `pnpm --filter=next types`, prettier, eslint — clean - `pnpm build-all` — 18/18 tasks - `test/production/next-server-nft` — 5/5 tests, 5/5 snapshots pass (covers the traced `turbopack-cache-seed.js`) ### End-to-end verification against a real old-format cache `create-next-app@16.3.0` + `next build` (with `turbopackFileSystemCacheForBuild`) on released `next@16.3.0` writes a `CURRENT` in the old pre-JSON format — a bare big-endian `u32` (`0000 0008`), 30M cache. This branch was then applied with `pnpm pack-next -p <app> -- --release` (release binary confirmed to contain `TURBO_ENGINE_VERSION_TTL_DAYS` and the new `CURRENT` field names), and two arms were run from an identical starting state — same cache, same code, only the env var differing: | Arm | Build | Cache dirs after | | --- | --- | --- | | `TURBO_ENGINE_VERSION_TTL_DAYS=0` | exit 0 | old dir **deleted**, 1 remains | | default TTL (3 days) | exit 0 | old dir **retained**, intact at 30M, 2 remain | The retention arm is the meaningful control: without #97268's fallback, `read_current_version` would error on the bare-`u32` file, the age would become `Duration::MAX`, and the directory would be evicted in *both* arms. Retention under the default TTL is direct evidence the mtime fallback works. Also confirmed: - new `CURRENT` is written as JSON: `{"max_sequence_number":8,"commit_time":"..."}` - retention cap holds: seeded 4 version dirs → build left exactly 2 (current + one most-recently-used other) - clean deletion, no `DELETION_PREFIX` leftovers in any run - `TURBO_ENGINE_VERSION_TTL_DAYS=notanumber` warns (`expected a whole number of days`) and falls back to the 3-day default rather than failing <!-- NEXT_JS_LLM -->