Skip to content

ESP32 integration suites exceed #806 900s cap on Windows; zccache persist_failed (tempdir nondeterminism) makes every framework rebuild cold #1347

Description

@zackees

Summary

The #[ignore]d ESP32 integration suites (esp32_build, eh_frame_strip_esp32) cannot complete a single clean esp32dev framework build within #806's 900 s cap on this Windows machine — and the compile backend's zccache layer gives them no relief, for two independent reasons discovered while repairing the #800 backend-install gap (phase-8b PR, #1346):

1. Sequential framework builds blow the 900 s cap

The esp32dev framework stage compiles sequentially at roughly 4 s/file on this machine (Windows + xtensa-gcc). The Arduino-ESP32 core is ~1500 files → ~100 minutes per cold build, vs the 900 s budget both eh_frame_strip_drops_firmware_at_least_150kb (two builds!) and the four esp32_build blink/fixture tests need. Observed twice: timeout panic at exactly the 900 s cap, 938 s and 1055 s wall respectively.

2. zccache never hits for these runs — stores are refused

Embedded-zccache journals (~/.fbuild/prod/zccache/v1.13.1/logs/) show the esp32 framework compiles are effectively never cached:

journal window hit miss error
rotation ending 2026-08-20 12:58 1 1761 91
rotation ending 2026-08-20 23:45 0 1838 2
current (2026-08-22 runs) 0 1558+

Two mechanisms in daemon-lifecycle.log:

  • daemon_cache_root_contended — a test process's embedded backend does not own the cache-root writer slot whenever any other fbuild process touched it recently; its stores then can't be committed locally.
  • persist_failed: "same cache key produced different staged output bytes" — the decisive one. Test builds run in a fresh tempfile::TempDir each invocation; the same content-keyed compile produces different output bytes across runs (almost certainly DWARF DW_AT_comp_dir/debug paths embedding the per-run tempdir), so zccache correctly refuses to persist them. Every subsequent run recompiles everything.

Real-daemon builds (stable project dirs) don't hit mechanism 2 — this is specific to fresh-tempdir test harnesses.

Impact

Suggested fixes (in dependency order)

  1. Deterministic debug paths for cached framework compiles-fdebug-prefix-map-style normalization (or drop -g for framework objects) so identical keys produce identical bytes and persist_failed stops eating every store.
  2. Test-process cache isolation — route test-launched CompileBackends at a scratch/dev cache root (the way FBUILD_DEV_MODE=1 isolates), so tests neither contend for nor pollute the prod writer slot.
  3. Parallelize the ESP32 framework stage (or revisit the sequential pipeline wall on Windows) — even fully cached-first-run builds will otherwise stay near the cap.
  4. Optionally: have the orchestrator emit per-stage progress into the test-visible log so future timeouts are diagnosable without the deleted-tempdir problem noted in compile_many_stage2_perf oracle: unrunnable since #800; with backend installed, stage-2 wall ~6.5s fails 50%-of-stage-1 bound — #337 seed regression or stale baseline #1346.

Repro

soldr cargo test -p fbuild-build --test eh_frame_strip_esp32 -- --include-ignored
# → panicked: real-toolchain test exceeded 900s budget — see FastLED/fbuild#806

Found during phase-8b verification; cross-referenced from #1346.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions