feat: import Chinese-localized Buzz source snapshot
Docker image / Build (linux/amd64) (push) Has been cancelled
Docker image / Build (linux/arm64) (push) Has been cancelled
Docker image / Merge release multi-arch manifest (push) Has been cancelled
Docker image / Merge debug multi-arch manifest (push) Has been cancelled
Docker image / Build public push gateway (linux/amd64) (push) Has been cancelled
Docker image / Build public push gateway (linux/arm64) (push) Has been cancelled
Docker image / Publish public push gateway image (push) Has been cancelled
Sprig image / Build (linux/amd64) (push) Has been cancelled
Sprig image / Build (linux/arm64) (push) Has been cancelled
Sprig image / Merge multi-arch manifest (push) Has been cancelled
Harbor Buzz Orchestra / Python tests and lint (push) Has been cancelled
CI / Detect Changed Paths (push) Has been cancelled
CI / Rust Lint (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Desktop Core (push) Has been cancelled
CI / Desktop Smoke E2E (1) (push) Has been cancelled
CI / Desktop Smoke E2E (2) (push) Has been cancelled
CI / Desktop Smoke E2E (3) (push) Has been cancelled
CI / Desktop Smoke E2E (4) (push) Has been cancelled
CI / Desktop (push) Has been cancelled
CI / Desktop E2E Relay (push) Has been cancelled
CI / Desktop E2E Integration (1/2) (push) Has been cancelled
CI / Desktop E2E Integration (2/2) (push) Has been cancelled
CI / Desktop E2E Integration (push) Has been cancelled
CI / Backend Integration (relay e2e) (push) Has been cancelled
CI / Relay E2E (push) Has been cancelled
CI / Web (push) Has been cancelled
CI / Mobile (push) Has been cancelled
CI / Security (push) Has been cancelled
CI / Dead Token Reference Guard (push) Has been cancelled
CI / Server Cross-Compile (aarch64-unknown-linux-musl) (push) Has been cancelled
CI / Server Cross-Compile (x86_64-unknown-linux-musl) (push) Has been cancelled
CI / Windows Rust (x86_64-pc-windows-msvc) (push) Has been cancelled
CI / Desktop Build (macOS) (push) Has been cancelled
helm chart / lint + unittest + render matrix (push) Has been cancelled
helm chart / install on kind (gated) (push) Has been cancelled
helm chart / publish chart to GHCR (push) Has been cancelled
Mesh Lifecycle / Relay-Driven Mesh Lifecycle Smoke (push) Has been cancelled
Sprig / Build (aarch64-unknown-linux-musl) (push) Has been cancelled
Sprig / Build (x86_64-unknown-linux-musl) (push) Has been cancelled
Sprig / Publish rolling release (push) Has been cancelled
Sprig / Publish tagged release (push) Has been cancelled

Signed-off-by: cls_宁波本机 <908705107@qq.com>
This commit is contained in:
2026-08-13 18:34:25 +08:00
parent 61c3fa1df9
commit 9dfa06ffee
3785 changed files with 1085458 additions and 2 deletions
@@ -0,0 +1,121 @@
//! Tokio worker stack-size smoke — reproduces and verifies the fix for the
//! mesh-llm model-download stack overflow (SIGABRT via stack guard).
//!
//! Crash report (2026-07-08, buzz-desktop 0.3.46): enabling Share compute
//! aborted the app on a `tokio-rt-worker` thread inside
//! `mesh_llm_host_runtime::models::resolve::download_model_ref_with_progress_details`
//! — Rust's stack-overflow signal handler fired on tokio's default 2 MiB
//! worker stack. Upstream mesh-llm runs its own binary on 8 MiB worker
//! stacks for exactly this reason (`DEFAULT_WORKER_STACK_SIZE` in mesh-llm
//! `main.rs`), as does mesh-console.
//!
//! This harness polls the same future as a spawned task (matching how Tauri
//! polls command futures on worker threads) in two subprocess legs:
//!
//! 1. 2 MiB worker stacks (tokio default) — expected to DIE from the
//! stack guard (signal, no exit code). Proves we reproduced the crash.
//! 2. 8 MiB worker stacks (the fix installed in desktop `lib.rs` via
//! `tauri::async_runtime::set`) — expected to complete the download.
//!
//! Each leg gets a fresh HF_HOME so the download really runs (a cache hit
//! never reaches the deep code path). Network required; downloads a ~100 MB
//! GGUF twice at most (leg 1 usually dies early). Not CI — run manually:
//!
//! cargo run -p buzz-relay --example mesh_stack_smoke
use std::process::{Command, Stdio};
/// Small real model, same one the admission smoke uses.
const MODEL: &str = "jc-builds/SmolLM2-135M-Instruct-Q4_K_M-GGUF:Q4_K_M";
const TOKIO_DEFAULT_STACK: usize = 2 * 1024 * 1024;
/// Must match `buzz_lib::mesh_llm::MESH_WORKER_STACK_SIZE` (desktop crate is
/// not a dependency of buzz-relay, so the value is duplicated here).
const FIXED_STACK: usize = 8 * 1024 * 1024;
fn main() -> anyhow::Result<()> {
match std::env::var("MESH_STACK_ROLE").ok().as_deref() {
Some("download") => role_download(),
_ => orchestrate(),
}
}
/// Subprocess: poll the download future as a spawned task on a worker
/// thread with the requested stack size — the exact shape of a Tauri
/// command future.
fn role_download() -> anyhow::Result<()> {
let stack: usize = std::env::var("MESH_STACK_SIZE")?.parse()?;
let runtime = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.thread_stack_size(stack)
.build()?;
runtime.block_on(async {
tokio::spawn(async {
mesh_llm_host_runtime::models::download_model_ref_with_progress_details(MODEL, true)
.await
.map(|_| ())
.map_err(|error| anyhow::anyhow!("download failed: {error}"))
})
.await?
})?;
println!("DOWNLOAD_OK");
// Skip destructors (ggml teardown abort, mesh-console issue #8).
std::process::exit(0);
}
fn run_leg(stack: usize, hf_home: &std::path::Path) -> anyhow::Result<(bool, Option<i32>)> {
let exe = std::env::current_exe()?;
let status = Command::new(exe)
.env("MESH_STACK_ROLE", "download")
.env("MESH_STACK_SIZE", stack.to_string())
.env("HF_HOME", hf_home)
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.status()?;
Ok((status.success(), status.code()))
}
fn orchestrate() -> anyhow::Result<()> {
let scratch = std::env::temp_dir().join(format!("mesh-stack-smoke-{}", std::process::id()));
println!(
"=== leg 1: {} MiB worker stacks (tokio default) — expecting stack-guard death ===",
TOKIO_DEFAULT_STACK / (1024 * 1024)
);
let hf1 = scratch.join("hf-2mb");
std::fs::create_dir_all(&hf1)?;
let (ok_2mb, code_2mb) = run_leg(TOKIO_DEFAULT_STACK, &hf1)?;
println!(
"=== leg 2: {} MiB worker stacks (the fix) — expecting success ===",
FIXED_STACK / (1024 * 1024)
);
let hf2 = scratch.join("hf-8mb");
std::fs::create_dir_all(&hf2)?;
let (ok_8mb, code_8mb) = run_leg(FIXED_STACK, &hf2)?;
let _ = std::fs::remove_dir_all(&scratch);
println!();
println!(
"leg 1 (2 MiB): success={ok_2mb} exit_code={code_2mb:?} (None = killed by signal, i.e. stack guard)"
);
println!("leg 2 (8 MiB): success={ok_8mb} exit_code={code_8mb:?}");
// Leg 2 is the hard gate: the fix must work.
if !ok_8mb {
anyhow::bail!("FAIL: download did not complete on 8 MiB worker stacks — fix is broken");
}
// Leg 1 documents the repro. If it *succeeds*, the overflow needs deeper
// nesting than this harness provides — flag loudly but do not fail, the
// fix leg is still proven.
if ok_2mb {
println!(
"WARNING: 2 MiB leg did not crash here; overflow requires the app's extra \
tauri/ipc nesting. Fix leg still verified."
);
} else {
println!("repro confirmed: 2 MiB worker stack dies, matching the crash report");
}
println!("PASS");
Ok(())
}