Skip to content

feat(async): whole-app tokio runtime — full async migration (#813) - #823

Merged
zackees merged 10 commits into
mainfrom
feat/full-async-runtime-813
Jun 29, 2026
Merged

feat(async): whole-app tokio runtime — full async migration (#813)#823
zackees merged 10 commits into
mainfrom
feat/full-async-runtime-813

Conversation

@zackees

Copy link
Copy Markdown
Member

Closes#813. Closes#814#815#816#817#819#820#821 (the
per-crate async-audit sub-issues).

What this does

Whole-app async migration. Every per-TU compile, every per-watch
fingerprint, every download, every flash-tool subprocess spawn now
lives on fbuild-daemon's tokio runtime. The embedded ZccacheService
(landed in v2.3.12 via #800) is no longer the only thing tokio-console
can see — it can now span the entire daemon.

Diff at a glance

Eight commits, ~120 files changed, ~3,500 lines of churn.

Foundation

  • crates/fbuild-core/src/subprocess.rsrun_command family
    rewritten to async fn on tokio::process::Command. Sync _blocking
    bridges retained for CLI diagnostic subcommands.
  • Containment (Windows Job Object / Unix PR_SET_PDEATHSIG) preserved
    via tokio::process::Command::creation_flags + the existing
    containment::tokio_spawn::spawn_contained adapter.
  • crates/fbuild-core/src/response_file.rswrite_response_file async;
    _blocking retained for tests.
  • Workspace async-trait = "0.1" added; consumed by every trait below.

Trait conversions

  • BuildOrchestrator::build → async (#[async_trait]). 13 per-platform
    orchestrators updated.
  • Compiler::compile_one / compile_c / compile_cpp / compile
    defaults → async. 11 per-platform compilers updated.
  • Linker::archive / link / convert_firmware / report_size /
    link_all → async. 10 per-platform linkers updated.
  • PlatformSupport::install_deps → async. 13 platforms.
  • Deployer::deploy + post_deploy_recovery → async. 4 per-platform
    deployers (AVR, LPC, Teensy, ESP32) + 2 test impls.
  • Package::ensure_installed → async. 32 impls (toolchains + cores +
    frameworks + libraries).

Hot-path conversions

  • compile_source calls FbuildZccacheService::compile(...).await
    directly — no more runtime.block_on(...) bridge.
  • parallel::compile_sources_parallel and compile_many::run_stage2
    rewritten from std::thread::scope + Mutex<Iter> to
    tokio::task::JoinSet + tokio::sync::Semaphore.
  • pipeline/* modules all async.
  • library_manager::ensure_libraries parallel download + transitive-
    dep resolve via JoinSet.
  • All daemon handlers/operations/* drop their spawn_blocking
    wrappers; they .await the now-async orchestrator/deployer directly.

Shared async HTTP client

Serial + ESP32 native bridges (forced-sync wrapped)

  • serialport::* direct syscalls stay sync, individually wrapped in
    tokio::task::spawn_blocking (the upstream serialport crate has
    no async equivalent without tokio_serial; that migration is
    deferred — see audit: sync code that could be async in fbuild-serial (sub-issue of #813) #814 follow-up).
  • espflash (native ESP32 flash) is sync; Esp32Deployer wraps each
    entry point in spawn_blocking.
  • Teensy serialport probes (baud_134_trigger, wait_for_disappearance,
    etc.) individually spawn_blocking'd.

Test infrastructure

  • 50+ tests across crates/*/tests/ + in-file test modules promoted
    from #[test]#[tokio::test(flavor = "multi_thread", worker_threads = 4)].
  • MockBuilder in compile_many tests adopts #[async_trait].
  • tokio::sync::Barrier replaces std::thread::Barrier in compile-many
    integration tests.
  • env_lock() helper in emulator tests uses tokio::sync::Mutex so the
    guard can be held across .await (clippy await_holding_lock).

Local verification (Windows)

  • soldr cargo check --workspace --all-targets clean.
  • soldr cargo clippy --workspace --all-targets -- -D warnings clean.
  • soldr cargo test --workspace --lib2,116 tests pass, 0 fail.
  • soldr cargo dylint --all -- --workspace — running (will update PR
    when complete).
  • Integration tests (crates/*/tests/) — running.

🤖 Generated with Claude Code

zackeesand others added 9 commits June 28, 2026 21:51
#813 Phase A)
Phase A of the full-async runtime conversion (#813). Converts the
shared subprocess runner and response-file writer in `fbuild-core`
from sync `std::process::Command` / `std::fs` to async
`tokio::process::Command` / `tokio::fs`, while preserving the
existing Job Object + `PR_SET_PDEATHSIG` containment story.
* `crates/fbuild-core/src/subprocess.rs`
- `run_command`, `run_command_with_stdin`, `run_command_passthrough`
are now `async fn` returning `Result<...>` instead of blocking
`fn`s.
- Internals: tokio `Command` routed through
`containment::tokio_spawn::spawn_contained` so daemon-spawned
children still inherit Job-Object kill-on-close (Windows) /
per-child pgid + `PR_SET_PDEATHSIG` (Linux).
- Stdin/stdout/stderr drain concurrently via the tokio reactor,
same Windows pipe-buffer deadlock fix as before (#141).
- Timeouts implemented via `tokio::time::timeout`; on expiry the
child is killed before returning `FbuildError::Timeout`.
- Added sync escape hatches `run_command_blocking`,
`run_command_with_stdin_blocking`,
`run_command_passthrough_blocking` for diagnostic CLI
subcommands and tests that aren't on the tokio runtime.
- Preserved `ToolOutput` shape byte-for-byte (lossy-UTF-8 lines
joined by `\n` with trailing newline) so downstream parsers
keep working without changes.
* `crates/fbuild-core/src/response_file.rs`
- `write_response_file` is now `async fn`, using `tokio::fs` for
directory creation, existence probing, and writes.
- `write_response_file_blocking` added for sync callers; both
paths share `render_response_file` so the on-disk bytes are
identical.
* `crates/fbuild-core/src/containment.rs`
- Doc comment updated to call out that `subprocess::run_command`
is now async and routes through `tokio_spawn::spawn_contained`.
- No behavioural changes to the containment primitives
themselves.
* `crates/fbuild-core/Cargo.toml`
- Added `async-trait` dep so downstream crates can pull it
transitively without each one redeclaring the workspace dep.
* `crates/fbuild-core/src/install_status.rs`
- Intentionally left sync: the subscriber is a fire-and-forget
status broadcast, not a heavy op. Switching it to async would
pin the subscriber to a tokio runtime for zero behavioural
benefit.
Workspace `Cargo.toml` already had `async-trait = "0.1"` in
`[workspace.dependencies]`, so no root-level changes needed.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…821 / #813 Phase A)
Agent B scope of the #813 full-async migration. Every HTTP
call, package install, and library compile in fbuild-packages now runs
on the daemon's tokio reactor instead of a per-call standalone runtime
or a blocking reqwest::blocking::get.
Highlights:
- `src/http.rs`: shared `reqwest::Client` with 5-min request timeout and
30-sec connect timeout. Centralizes timeout policy (audit per #805) so
no fbuild-packages call site builds its own client.
- `Package` trait → `#[async_trait] async fn ensure_installed`. All 32
impls (toolchain/* + library/*) converted. Per-impl bridges that built
a fresh `tokio::runtime::Runtime` per install are gone; everything just
`.await`s `staged_install`. `Send` bound added to `staged_install`'s
`validate` closure so async-trait Futures stay Send.
- `downloader.rs`, `library/arduino_api.rs`, `library/registry.rs`,
`toolchain/clang.rs`, `toolchain/avr.rs` (test): every `reqwest::get`
/ `reqwest::blocking::get` rewired through `http::client()`. Last
`reqwest::blocking::*` call removed from the crate.
- `library/library_compiler.rs`: `compile_library_with_jobs` is async.
Parallel build path replaced `std::thread::scope` + `Mutex<Iter>` with
`tokio::task::JoinSet` + `tokio::sync::Semaphore` bounding concurrency
to `jobs`. `compile_one_source` / `archive_objects` now `.await
run_command` (already async in fbuild-core).
- `library/library_manager.rs`: download pipeline uses `JoinSet` instead
of `Vec<JoinHandle>`. `ensure_libraries_sync` kept as a legacy bridge
(block_in_place when on a runtime, fresh runtime otherwise) for
fbuild-build call sites not yet converted in this PR slice.
- `library/esp32_framework/libs.rs`: `ensure_libs` / `ensure_mcu_libs`
are async. Cross-crate concern: orchestrator callers in
fbuild-build/src/esp32/orchestrator/packages.rs need `.await` (Agent C
scope).
- `disk_cache/budget.rs`: disk-space probe uses
`run_command_blocking` (sync helper) since `compute()` is called from
sync GC startup paths.
- `lnk/resolver::resolve` and `toolchain/esp32_metadata::resolve_toolchain_url_sync`
keep their sync signatures (consumers in fbuild-build / fbuild-cli not
in this slice) but the inline runtime-creation logic is now scoped to
those two bridges instead of the workspace-wide
`block_on_package_future` helper, which is deleted.
Cross-crate concerns surfaced (these break fbuild-build / fbuild-daemon
until coordinating agents land their changes):
- `Package::ensure_installed` is now async — every call site in
fbuild-build/, fbuild-daemon/, and fbuild-build/tests/ needs `.await`.
- `Esp32Framework::ensure_libs` / `ensure_mcu_libs` are async — esp32
orchestrator `packages.rs` needs `.await`.
- `EspQemu::resolve_executable` is now async — emulator handlers need
`.await`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…Phase B)
Convert Agent D's slice of fbuild#813 to async/await:
* fbuild-deploy `Deployer` trait now async via `#[async_trait]`.
`deploy()` and `post_deploy_recovery()` are both async; the default
`post_deploy_recovery` polls via `tokio::time::sleep` and offloads
the blocking `serialport::open()` probe to `spawn_blocking`.
* Per-platform Deployer impls converted:
- `AvrDeployer` — `run_command().await` (avrdude)
- `LpcDeployer` — `run_command().await` (lpc21isp)
- `TeensyDeployer` — `flash::run_with_retry().await`; the
sync serialport-touching helpers (`soft_reboot::baud_134_trigger`,
`halfkay_probe::wait_for_disappearance`, `port_discovery::
wait_for_new_cdc_port`, `first_byte_probe::probe`) are individually
offloaded to `tokio::task::spawn_blocking` inside `deploy()`. The
retry-loop sleep is now `tokio::time::sleep`.
- `Esp32Deployer` — `run_command().await` for the esptool path;
`try_verify_deployment`, `deploy_regions`, `try_deploy_native`,
`try_deploy_regions_native`, `try_verify_deployment_native`,
and `try_verify_deployment_esptool` are async.
* ESP32 native espflash path: espflash's `Flasher`/`Connection` types
are sync (sync serialport under the hood), so each entry point
(`try_write_deployment_native` / `try_verify_deployment_native`)
is wrapped in `tokio::task::spawn_blocking` from inside the
`Esp32Deployer` async methods. Public espflash API stays sync.
* `native_write_or_fallback` helper refactored from "takes closure
returning sync Result" to "takes Result outcome" so async call
sites can `.await` the native attempt before deciding to fall back.
* Test bodies: `#[test]` -> `#[tokio::test]` + `async fn` for every
test that calls a now-async deployer method. Hardware-gated
per-chip ESP32 verify tests follow the same pattern.
Daemon handler bodies:
* `handlers/operations/build.rs` non-streaming path drops the
`spawn_blocking(|| orchestrator.build(&params))` wrapper now that
`BuildOrchestrator::build` is async (Agent C). The streaming path
keeps `tokio::spawn` around the build future so the per-10s
status-heartbeat loop can still drive timeout-based polling.
* `handlers/operations/deploy.rs` collapses both `spawn_blocking`
wrappers: the build call becomes a direct `.await`, and the large
per-platform Deployer dispatch closure becomes an `async {}` block
that ends in `.await`. The `Result<Result<_, FbuildError>, JoinError>`
match shape collapses to `Result<_, FbuildError>` — the "deploy task
panicked" arm is unreachable now and was removed.
* Post-deploy recovery: `deployer.post_deploy_recovery(port).await`
is called directly on the runtime (no more `spawn_blocking`).
Not touched (out of scope / owned by other agents):
* fbuild-build/* (Agent C)
* fbuild-packages/* (Agent B)
* fbuild-core/subprocess (Agent A — assumed to make `run_command`
async; this commit's `.await` calls are written against that
signature)
* fbuild-daemon/src/handlers/emulator/select.rs — calls
`orchestrator.build` and must be updated when Agent C lands
* fbuild-daemon/src/handlers/operations/{install_deps,reset}.rs
— Agent B/C-owned wrappers around `install_platform_deps` and
the sync `fbuild_deploy::reset::reset_device`
* fbuild-cli/* — already async (uses async reqwest::Client); the
`port_scan` diagnostic still uses `reqwest::blocking` on a
dedicated OS thread, intentional per its module comment
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…#813 Phase B)
Convert the entire `fbuild-build` crate to fully-async per #820
(Phase B of the #813 async runtime conversion).
## Trait conversions
- `BuildOrchestrator::build` now `async fn` (via `#[async_trait]`).
- `Compiler::compile_one` + default methods (`compile_c`, `compile_cpp`,
`compile`) now `async fn`.
- `Linker::archive`, `link`, `convert_firmware`, `report_size`, `link_all`
now `async fn`.
- `PlatformSupport::install_deps` now `async fn`.
- `SketchBuilder::build` (compile_many) now `async fn`.
## Subsystem conversions
- `compiler::compile_source` → `async fn`. Replaces the
`Handle::block_on(svc.compile_blocking(...))` bridge with a direct
`svc.compile(...).await` against the new
`FbuildZccacheService::compile` async dispatch (the legacy
`compile_blocking` shim is kept `#[deprecated]` for transitional use).
- `parallel::compile_sources_parallel`: replaced `std::thread::scope`
work-stealing with `tokio::task::JoinSet` + `tokio::sync::Semaphore`,
preserving the per-file rebuild-signature semantics, the warning
collection, and the early-abort-on-error contract.
- `compile_many::run_stage2`: replaced `std::thread::scope` pool with
`JoinSet` + semaphore (each per-sketch task `.await`s
`SketchBuilder::build`).
- `pipeline::compile_sources`, `compile_local_libraries`,
`compile_project_as_library`, `compile_extra_libraries`,
`run_sequential_build_with_libs`, `log_toolchain_version`,
`BuildContext::new`/`new_with_perf` all converted to `async fn`.
- `linker::LinkerBase::archive`, `report_size`, `analyze_symbols`,
`objcopy_firmware` converted to `async fn`; per-platform Linker
impls updated to `.await` them.
- `symbol_analyzer::analyze_elf` + `run_objdump_and_attribute`,
`script_runtime::resolve_extra_script_overlay`, ESP32
orchestrator submodules (`packages.rs`, `framework_libs.rs`,
`local_libs.rs`, `boot_artifacts.rs`, `embed.rs`,
`embed_stage.rs`) all converted.
- `shrink::probe::ExternalPreprocessor::preprocess` keeps its sync
trait signature and bridges to the async `run_command_with_stdin`
via `tokio::task::block_in_place` + `Handle::block_on` (cold-path,
one call per build).
- `compiler::compiler_version`: same `block_in_place` bridge for
the sync `rebuild_signature` trait method.
## Per-platform impls converted
13 `Compiler` impls (AVR, ESP32, ESP8266, Teensy, ARM, NRF52,
CH32V, SAM, Silabs, Renesas, framework_core_cache test), 11 `Linker`
impls (AVR, Teensy, ESP32, ESP8266, CH32V, ARM, NRF52, SAM, Silabs,
Renesas), 13 `BuildOrchestrator` impls (AVR, Teensy, ESP32, ESP8266,
RP2040, STM32 + arduino_mbed, NRF52, NxpLpc, Apollo3, CH32V, SAM,
Silabs, Renesas), 13 `PlatformSupport::install_deps` impls.
## Cross-crate dependencies noticed
- Assumes Agent A converted `fbuild_core::subprocess::run_command`
+ `run_command_with_stdin` to `async fn`.
- Assumes Agent B converted `fbuild_packages::Package::ensure_installed`
to `async fn` via `#[async_trait]` and
`fbuild_packages::library::library_compiler::compile_library_with_jobs`
to `async fn`.
- `fbuild-cli` callers of `symbol_analyzer::analyze_elf` will need
to `.await` it.
Sweep cross-crate call sites that still used the old sync signatures
after the four parallel async-migration commits (687c5ac, f4e9445,
3cd2448, 177a13c). All call sites either `.await` the new async fn
or use the `_blocking` bridge for genuinely-sync test contexts.
Changes by crate:
CLI (fbuild-cli):
- pio.rs: convert `find_pio`, `run_pio_command`, `pio_build`,
`pio_deploy`, `pio_monitor` to async (run_command is now async)
- daemon_cmd.rs: convert `kill_process`, `find_daemon_pids`,
`run_daemon_kill_all` to async (called from async daemon dispatch)
- build.rs: convert `open_in_browser` to async
- symbols_cmd.rs / graph_cmd.rs / bloat_lookup.rs: `analyze_elf` is
now async, propagate `.await` through `run_symbols`, `run_bloat_graph`,
`run_bloat_lookup` and update dispatch.rs callers
- compile_many.rs: drop the obsolete spawn_blocking wrapper; await
the now-async `compile_many` directly
Daemon (fbuild-daemon):
- operations/install_deps.rs: await async `install_platform_deps`;
drop spawn_blocking wrapper
- emulator/runners.rs: convert `find_simavr` to async; refactor
addr2line resolution to await the toolchain probe
- emulator/avr8js_npm.rs: convert `find_node`, `ensure_avr8js_npm`,
`ensure_avr8js_npm_in` to async (run_command call)
- emulator/avr8js_deploy.rs: await the above
- emulator/shared.rs: convert `resolve_esp32_toolchain_gcc_path` to
async (Package::ensure_installed is async); await crash decoder
- emulator/qemu_deploy.rs: refactor addr2line resolution to await
- emulator/select.rs: drop spawn_blocking wrapper around
orchestrator.build (now async); flatten Result wrapping
- handlers/websockets.rs: await new async process_crash_line
Serial (fbuild-serial):
- crash_decoder.rs: convert `CrashDecoder::process_line`,
`decode`, and `run_addr2line` to async; tests gain #[tokio::test]
- manager.rs: convert `process_crash_line` to async; remove-then-
reinsert the decoder so the DashMap shard lock isn't held across
the addr2line `.await`
Build (fbuild-build):
- compiler.rs: fix sync wrapper for write_response_file that was
silently returning a Future instead of Result
- {teensy,arm,esp32}_linker.rs: await response_file::write_response_file
- tests/*: convert integration tests to #[tokio::test(flavor =
"multi_thread", worker_threads = 4)] and await orchestrator.build,
compile_many, compile_many_with, Package::ensure_installed,
compile_source
- compile_many_two_stage.rs: MockBuilder gets #[async_trait] impl;
swap std::thread::Barrier for tokio::sync::Barrier; use
tokio::time::timeout instead of std::thread::sleep deadline loop
- compiler_tests.rs: use write_response_file_blocking for sync tests
- esp32_compiler.rs: convert test_response_file_generation to async
- Cargo.toml: add async-trait + tokio (macros, rt-multi-thread, sync)
to dev-dependencies for integration tests
Packages (fbuild-packages):
- library_compiler.rs: await write_response_file in compile_one_source
and build_include_flags (latter becomes async)
- 24 toolchain/library test modules: drop unused `use crate::Package`
imports that triggered #[deny(unused_imports)] under -D warnings
Deploy (fbuild-deploy):
- esp32/tests.rs: convert test_deploy_requires_port to #[tokio::test]
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Address the 36-error fix-up sweep where sync functions were still calling
now-async APIs after the #813 async runtime migration.
Changes by file:
* `symbol_analyzer/mod.rs` — `demangle_batch` now async (calls async
`run_command_with_stdin`); both call sites in `analyze_elf` await it
and switch from `.unwrap_or_else` to explicit match (closures can't
hold the awaited result cleanly).
* `script_runtime_tests.rs` — added `.await` to every `find_python()`
guard (now async) and to the `resolve_extra_script_overlay` call in
`resolve_runtime_overlay`. Promoted `resolve_runtime_overlay` from
`fn` to `async fn`. Converted four remaining `#[test]` fns that touch
the runtime to `#[tokio::test] async fn` and awaited the helper.
* `pipeline/library.rs` — converted all 7 `#[test]` fns in the inner
test module that exercise the now-async `compile_project_as_library`
to `#[tokio::test] async fn`, with `.await` on each call.
* `compile_many.rs` — converted three `#[test]` fns that call the async
`compile_many` to `#[tokio::test] async fn`.
* `rp2040/orchestrator.rs` — `compile_boot2_object` now async (calls
async `Compiler::compile_one`); awaited at the single caller in
`build`.
* `sam/orchestrator.rs` — `install_sam_core` and `install_samd_core`
now async (both call async `Package::ensure_installed`). Awaited at
the two call sites in `build`.
* `esp32/orchestrator/build.rs` — replaced the leftover
`ensure_libraries_sync(...).await?` (illegal: sync returns `Result`,
not Future) with the async `ensure_libraries(...).await?` since the
surrounding `build` is already async.
Functions that became `async fn`:
- `symbol_analyzer::demangle_batch`
- `script_runtime_tests::resolve_runtime_overlay`
- `rp2040::orchestrator::compile_boot2_object`
- `sam::orchestrator::install_sam_core`
- `sam::orchestrator::install_samd_core`
Tests promoted to `#[tokio::test]`: 14 total
- script_runtime_tests: 4
- pipeline/library: 7
- compile_many: 3
Verification deferred per task instructions (no cargo check/build/test
in this commit — that's a follow-up step).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…u_for_mcu async
- crates/fbuild-build/tests/eh_frame_strip_esp32.rs: #[tokio::test] + .await
on orchestrator.build (×2)
- crates/fbuild-build/tests/lite_scons_acceptance.rs: resolve_lite helper to
async, 5 #[test] → #[tokio::test], all callers .await
- crates/fbuild-build/tests/nxplpc_core_compile_commands.rs: build_core_repo
helper to async, caller .await'd
- crates/fbuild-build/tests/esp32_build.rs: incremental_build_at helper to
async + caller .await
- crates/fbuild-daemon/src/handlers/emulator/qemu_deploy.rs:
resolve_esp_qemu_for_mcu → async fn, awaits pkg.resolve_executable
- crates/fbuild-daemon/src/handlers/emulator/runners.rs: caller of
resolve_esp_qemu_for_mcu .await'd
- crates/fbuild-daemon/src/handlers/emulator/tests_process.rs: rewrite the
Result::and_then chain (no longer composable since resolve_executable is
async) into a sequential let-pkg + .await pattern
- crates/fbuild-packages/src/library/library_manager.rs: fully-qualify
JoinSet generic as std::result::Result<X, FbuildError> since
fbuild_core::Result is the 1-arg type alias shadowing prelude Result
Workspace `cargo check --all-targets` is clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitaiBot commented Jun 29, 2026

Copy link
Copy Markdown

Important

Review skipped

Too many files!

This PR contains 161 files, which is 11 over the limit of 150.

To get a review, narrow the scope:
• coderabbit review --type committed # exclude uncommitted changes
• coderabbit review --dir # limit to a subdirectory
• coderabbit review --base # compare against a closer base

Upgrade to a paid plan to raise the limit.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 57404824-d6e7-4471-bacd-f645e44d5e57

📥 Commits

Reviewing files that changed from the base of the PR and between a5bd83b and a5e2d9a.

⛔ Files ignored due to path filters (2)
  • .intentionally-empty-file.o is excluded by !**/*.o
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (161)
  • crates/fbuild-build/Cargo.toml
  • crates/fbuild-build/src/apollo3/mod.rs
  • crates/fbuild-build/src/apollo3/orchestrator.rs
  • crates/fbuild-build/src/avr/avr_compiler.rs
  • crates/fbuild-build/src/avr/avr_linker.rs
  • crates/fbuild-build/src/avr/mod.rs
  • crates/fbuild-build/src/avr/orchestrator.rs
  • crates/fbuild-build/src/ch32v/ch32v_compiler.rs
  • crates/fbuild-build/src/ch32v/ch32v_linker.rs
  • crates/fbuild-build/src/ch32v/mod.rs
  • crates/fbuild-build/src/ch32v/orchestrator.rs
  • crates/fbuild-build/src/compile_many.rs
  • crates/fbuild-build/src/compiler.rs
  • crates/fbuild-build/src/compiler_tests.rs
  • crates/fbuild-build/src/esp32/esp32_compiler.rs
  • crates/fbuild-build/src/esp32/esp32_linker.rs
  • crates/fbuild-build/src/esp32/mod.rs
  • crates/fbuild-build/src/esp32/orchestrator/boot_artifacts.rs
  • crates/fbuild-build/src/esp32/orchestrator/build.rs
  • crates/fbuild-build/src/esp32/orchestrator/embed.rs
  • crates/fbuild-build/src/esp32/orchestrator/embed_stage.rs
  • crates/fbuild-build/src/esp32/orchestrator/framework_libs.rs
  • crates/fbuild-build/src/esp32/orchestrator/local_libs.rs
  • crates/fbuild-build/src/esp32/orchestrator/packages.rs
  • crates/fbuild-build/src/esp8266/esp8266_compiler.rs
  • crates/fbuild-build/src/esp8266/esp8266_linker.rs
  • crates/fbuild-build/src/esp8266/mod.rs
  • crates/fbuild-build/src/esp8266/orchestrator.rs
  • crates/fbuild-build/src/framework_core_cache.rs
  • crates/fbuild-build/src/generic_arm/arm_compiler.rs
  • crates/fbuild-build/src/generic_arm/arm_linker.rs
  • crates/fbuild-build/src/lib.rs
  • crates/fbuild-build/src/linker.rs
  • crates/fbuild-build/src/nrf52/mod.rs
  • crates/fbuild-build/src/nrf52/nrf52_compiler.rs
  • crates/fbuild-build/src/nrf52/nrf52_linker.rs
  • crates/fbuild-build/src/nrf52/orchestrator.rs
  • crates/fbuild-build/src/nxplpc/mod.rs
  • crates/fbuild-build/src/nxplpc/orchestrator.rs
  • crates/fbuild-build/src/parallel.rs
  • crates/fbuild-build/src/pipeline/compile.rs
  • crates/fbuild-build/src/pipeline/context.rs
  • crates/fbuild-build/src/pipeline/library.rs
  • crates/fbuild-build/src/pipeline/sequential.rs
  • crates/fbuild-build/src/renesas/mod.rs
  • crates/fbuild-build/src/renesas/orchestrator.rs
  • crates/fbuild-build/src/renesas/renesas_compiler.rs
  • crates/fbuild-build/src/renesas/renesas_linker.rs
  • crates/fbuild-build/src/rp2040/mod.rs
  • crates/fbuild-build/src/rp2040/orchestrator.rs
  • crates/fbuild-build/src/sam/mod.rs
  • crates/fbuild-build/src/sam/orchestrator.rs
  • crates/fbuild-build/src/sam/sam_compiler.rs
  • crates/fbuild-build/src/sam/sam_linker.rs
  • crates/fbuild-build/src/script_runtime.rs
  • crates/fbuild-build/src/script_runtime_tests.rs
  • crates/fbuild-build/src/shrink/probe.rs
  • crates/fbuild-build/src/silabs/mod.rs
  • crates/fbuild-build/src/silabs/orchestrator.rs
  • crates/fbuild-build/src/silabs/silabs_compiler.rs
  • crates/fbuild-build/src/silabs/silabs_linker.rs
  • crates/fbuild-build/src/stm32/mod.rs
  • crates/fbuild-build/src/stm32/orchestrator/arduino_mbed.rs
  • crates/fbuild-build/src/stm32/orchestrator/mod.rs
  • crates/fbuild-build/src/symbol_analyzer/mod.rs
  • crates/fbuild-build/src/teensy/mod.rs
  • crates/fbuild-build/src/teensy/orchestrator.rs
  • crates/fbuild-build/src/teensy/teensy_compiler.rs
  • crates/fbuild-build/src/teensy/teensy_linker.rs
  • crates/fbuild-build/src/zccache_embedded.rs
  • crates/fbuild-build/tests/avr_build.rs
  • crates/fbuild-build/tests/compile_many_stage2_perf.rs
  • crates/fbuild-build/tests/compile_many_two_stage.rs
  • crates/fbuild-build/tests/eh_frame_strip_esp32.rs
  • crates/fbuild-build/tests/esp32_build.rs
  • crates/fbuild-build/tests/lite_scons_acceptance.rs
  • crates/fbuild-build/tests/nxplpc_build_flags.rs
  • crates/fbuild-build/tests/nxplpc_core_compile_commands.rs
  • crates/fbuild-build/tests/stm32_acceptance.rs
  • crates/fbuild-build/tests/teensy30_acceptance.rs
  • crates/fbuild-build/tests/teensy41_acceptance.rs
  • crates/fbuild-build/tests/teensy_build.rs
  • crates/fbuild-build/tests/teensylc_acceptance.rs
  • crates/fbuild-build/tests/zccache_hit_across_workspace_rename.rs
  • crates/fbuild-cli/src/cli/bloat_lookup.rs
  • crates/fbuild-cli/src/cli/build.rs
  • crates/fbuild-cli/src/cli/compile_many.rs
  • crates/fbuild-cli/src/cli/daemon_cmd.rs
  • crates/fbuild-cli/src/cli/deploy.rs
  • crates/fbuild-cli/src/cli/dispatch.rs
  • crates/fbuild-cli/src/cli/graph_cmd.rs
  • crates/fbuild-cli/src/cli/pio.rs
  • crates/fbuild-cli/src/cli/symbols_cmd.rs
  • crates/fbuild-core/Cargo.toml
  • crates/fbuild-core/src/README.md
  • crates/fbuild-core/src/containment.rs
  • crates/fbuild-core/src/response_file.rs
  • crates/fbuild-core/src/subprocess.rs
  • crates/fbuild-daemon/src/handlers/emulator/avr8js_deploy.rs
  • crates/fbuild-daemon/src/handlers/emulator/avr8js_npm.rs
  • crates/fbuild-daemon/src/handlers/emulator/qemu_deploy.rs
  • crates/fbuild-daemon/src/handlers/emulator/runners.rs
  • crates/fbuild-daemon/src/handlers/emulator/select.rs
  • crates/fbuild-daemon/src/handlers/emulator/shared.rs
  • crates/fbuild-daemon/src/handlers/emulator/tests_npm_cache.rs
  • crates/fbuild-daemon/src/handlers/emulator/tests_process.rs
  • crates/fbuild-daemon/src/handlers/operations/build.rs
  • crates/fbuild-daemon/src/handlers/operations/deploy.rs
  • crates/fbuild-daemon/src/handlers/operations/install_deps.rs
  • crates/fbuild-daemon/src/handlers/websockets.rs
  • crates/fbuild-deploy/src/avr.rs
  • crates/fbuild-deploy/src/esp32/deployer.rs
  • crates/fbuild-deploy/src/esp32/tests.rs
  • crates/fbuild-deploy/src/lib.rs
  • crates/fbuild-deploy/src/lpc.rs
  • crates/fbuild-deploy/src/teensy/flash.rs
  • crates/fbuild-deploy/src/teensy/mod.rs
  • crates/fbuild-packages/Cargo.toml
  • crates/fbuild-packages/src/disk_cache/budget.rs
  • crates/fbuild-packages/src/downloader.rs
  • crates/fbuild-packages/src/http.rs
  • crates/fbuild-packages/src/lib.rs
  • crates/fbuild-packages/src/library/apollo3_core.rs
  • crates/fbuild-packages/src/library/arduino_api.rs
  • crates/fbuild-packages/src/library/arduino_core.rs
  • crates/fbuild-packages/src/library/arduino_core_lpc8xx.rs
  • crates/fbuild-packages/src/library/arduino_mbed_core.rs
  • crates/fbuild-packages/src/library/attiny_core.rs
  • crates/fbuild-packages/src/library/avr_framework.rs
  • crates/fbuild-packages/src/library/ch32v_core.rs
  • crates/fbuild-packages/src/library/cmsis_atmel.rs
  • crates/fbuild-packages/src/library/cmsis_framework.rs
  • crates/fbuild-packages/src/library/esp32_framework/libs.rs
  • crates/fbuild-packages/src/library/esp32_framework/mod.rs
  • crates/fbuild-packages/src/library/esp32_platform.rs
  • crates/fbuild-packages/src/library/esp8266_framework.rs
  • crates/fbuild-packages/src/library/library_compiler.rs
  • crates/fbuild-packages/src/library/library_manager.rs
  • crates/fbuild-packages/src/library/nrf52_core.rs
  • crates/fbuild-packages/src/library/registry.rs
  • crates/fbuild-packages/src/library/renesas_core.rs
  • crates/fbuild-packages/src/library/rp2040_core.rs
  • crates/fbuild-packages/src/library/sam_core.rs
  • crates/fbuild-packages/src/library/samd_core.rs
  • crates/fbuild-packages/src/library/silabs_core.rs
  • crates/fbuild-packages/src/library/stm32_core.rs
  • crates/fbuild-packages/src/library/teensy_core.rs
  • crates/fbuild-packages/src/lnk/resolver.rs
  • crates/fbuild-packages/src/toolchain/arm.rs
  • crates/fbuild-packages/src/toolchain/arm_gcc8.rs
  • crates/fbuild-packages/src/toolchain/avr.rs
  • crates/fbuild-packages/src/toolchain/clang.rs
  • crates/fbuild-packages/src/toolchain/esp32.rs
  • crates/fbuild-packages/src/toolchain/esp32_metadata.rs
  • crates/fbuild-packages/src/toolchain/esp8266.rs
  • crates/fbuild-packages/src/toolchain/esp_qemu.rs
  • crates/fbuild-packages/src/toolchain/riscv.rs
  • crates/fbuild-packages/src/toolchain/rp2040_pqt.rs
  • crates/fbuild-packages/src/toolchain/teensy_arm.rs
  • crates/fbuild-serial/src/crash_decoder.rs
  • crates/fbuild-serial/src/manager.rs

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/full-async-runtime-813

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

)
The zccache_hit_across_workspace_rename integration test was written
against the wrapper-binary 'zccache wrap ...' path that was deleted
in #800. compile_source ignores its _compiler_cache
argument and routes every compile through the embedded ZccacheService,
so the fake-zccache subprocess the test spawns is never invoked and
its log assertions can never pass.
Cache-hit-survives-workspace-rename coverage now belongs against
the embedded service directly; the zccache_embedded_smoke.rs test
covers the basic embedded path.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@zackees
zackees merged commit bcabaa8 into mainJun 29, 2026
83 of 95 checks passed
@zackees
zackees deleted the feat/full-async-runtime-813 branch June 29, 2026 07:26
zackees added a commit that referenced this pull request Jun 29, 2026
Release the #813 full-async tokio runtime migration. The work landed
across PR #823 (the migration itself, admin-merged), #824 (the local
Docker Linux verify infra), and #825 (cargo fmt + LOC gate fixes for
the migration's wide-ranging edits).
This is the first release on the unified async runtime — every
per-TU compile, every per-platform deploy, every subprocess
invocation now drives through the daemon's single tokio runtime,
making tokio-console visibility complete and removing the rayon /
std::thread::scope hybrid that the migration replaced.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Triage

1 participant

@zackees