# SpacetimeDB publish sccache 降级处理 ## 背景 Windows 本地执行 `npm run dev:rust` 或 `spacetime publish` 时,`spacetime` 会在内部调用 Cargo 构建 `server-rs/crates/spacetime-module`。当前本地开发 publish 会追加 `--build-options="--debug"`,让 SpacetimeDB CLI 用 debug 构建参数编译模块。因为 `server-rs/.cargo/config.toml` 配置了 `rustc-wrapper = "sccache"`,即使当前 shell 没有设置 `RUSTC_WRAPPER`,Cargo 仍会先执行 `sccache rustc -vV`。 当本机 sccache server 状态损坏、client/server 通信异常或版本残留不一致时,可能出现: ```text sccache: error: Timed out waiting for server startup. Maybe the remote service is unreachable? sccache: error: failed to execute compile sccache: caused by: Failed to send data to or receive data from server sccache: caused by: Failed to read response header sccache: caused by: failed to fill whole buffer ``` 这类错误发生在 rustc wrapper 层,不能说明 SpacetimeDB module 代码本身编译失败。 ## 2026-05-11 本机根因定位 本机 `cargo check -p api-server` 失败时,Cargo 还没有进入业务 crate 编译,而是在读取 `server-rs/.cargo/config.toml` 后执行 `sccache rustc -vV` 探测编译器版本。失败的 stderr 会被写入 `server-rs/target/.rustc_info.json`,内容为 `Timed out waiting for server startup`。 当前 PowerShell 环境设置了 `SCCACHE_OSS_BUCKET=genarrative-sccache`、`SCCACHE_OSS_ENDPOINT=https://oss-rg-china-mainland.aliyuncs.com` 和 `SCCACHE_OSS_KEY_PREFIX=genarrative`,且没有设置本地 `SCCACHE_DIR`。因此 sccache daemon 冷启动时会先初始化 OSS 远端缓存,并执行 `.sccache_check` 的读写检查;日志中可见 `Init oss cache ...`、`proxy(http://127.0.0.1:7897/) intercepts ...`,随后才出现 `server started, listening on 127.0.0.1:4226`。 本次排查的结论是:冷启动失败主要发生在 sccache client 等待 daemon 启动的握手窗口内,而 daemon 启动又依赖 OSS/本机代理链路先完成缓存可读写检查。代理或 OSS 链路稍慢时,Cargo 调用的 `sccache rustc -vV` 会先超时;daemon 预热后直接执行同一条 `sccache rustc -vV` 又可能成功,所以这是冷启动/通道状态问题,不是 `api-server` 或 Rust 代码错误。 辅助证据: 1. `rustc -vV` 可直接输出版本,说明 Rust 工具链本身可用。 2. `tasklist` 曾只看到 `sccache --show-stats` 客户端进程,`netstat` 只出现到 `127.0.0.1:4226` 的 `SYN_SENT`,没有真正的 `LISTEN`,说明当时 client 正在等一个尚未成功监听的 daemon。 3. 在子进程中临时清掉 `SCCACHE_OSS_*` 并设置本地 `SCCACHE_DIR` 后,sccache 退回本地磁盘缓存,日志显示 `Init disk cache ...`,`rustc -vV` 和 `sccache --show-stats` 均能完成。 4. `C:\Users\DSK\AppData\Roaming\Mozilla\sccache\config\config` 缺失只是非致命 warning,本机实际配置来自环境变量。 ## 本地开发处理 `scripts/dev-rust-stack.sh` 的 publish 阶段继续由 SpacetimeDB CLI 内部调用 Cargo,并通过 `--build-options="--debug"` 使用 debug 构建参数。遇到 sccache 冷启动超时时,优先保留 `sccache` wrapper,并修复 sccache daemon 的启动等待时间;只有在排除 sccache 本身问题时,才临时绕过 wrapper 验证 rustc 本身可用。 该处理不修改 `server-rs/.cargo/config.toml`,也不删除本地 target 缓存。 ## 手动排障命令 优先确认 rustc 本身可用: ```bash rustc -vV ``` 如果要保留 sccache 并修复冷启动等待时间,在 PowerShell 中创建或更新 sccache 默认配置: ```powershell $configDir = Join-Path $env:APPDATA "Mozilla\sccache\config" New-Item -ItemType Directory -Force -Path $configDir | Out-Null @( "# Windows 本机 sccache 冷启动需要先完成 OSS 缓存读写检查。" "# 拉长 client 等待 daemon 启动的时间,避免 Cargo 在 rustc -vV 阶段误判超时。" "server_startup_timeout_ms = 60000" ) | Set-Content -Encoding UTF8 -Path (Join-Path $configDir "config") ``` 随后清掉 Cargo 曾缓存的失败探测结果,并从冷启动验证: ```powershell cd C:\proj\Genarrative\server-rs sccache --stop-server Remove-Item -Force target\.rustc_info.json -ErrorAction SilentlyContinue cargo check -p api-server ``` 注意:不要在另一个 `cargo` / `rustc` 仍在编译时执行 `taskkill /F /IM sccache.exe /T`。sccache 对 proc-macro crate 会显示 `Server sent UnhandledCompile` 并把请求转交给真实 rustc;如果此时强杀 sccache client/server,可能让 `serde_derive`、`spacetimedb-bindings-macro` 等 proc-macro 编译直接以 `sccache ... exit code: 1` 失败,而 stderr 里看不到真正的 Rust 诊断。这是排障动作打断编译,不是 `spacetime-module` 源码错误。 如果只想临时绕过本次 Cargo 构建的 sccache wrapper,可在 Git Bash 中执行: ```bash cd server-rs/crates/spacetime-module RUSTC_WRAPPER= CARGO_BUILD_RUSTC_WRAPPER= cargo check --target=wasm32-unknown-unknown ``` PowerShell 原生 Cargo 的一次性 wrapper 绕过命令是: ```powershell cd C:\proj\Genarrative\server-rs cargo check -p api-server --config "build.rustc-wrapper=''" ``` 如果需要验证是否为 OSS/代理冷启动问题,可只在当前 PowerShell 进程中切到本地缓存做对照: ```powershell $env:SCCACHE_LOG = "debug" $env:SCCACHE_ERROR_LOG = "C:\proj\Genarrative\logs\sccache-local-start-error.log" $env:SCCACHE_DIR = Join-Path $env:TEMP "genarrative-sccache-local-test" Remove-Item Env:SCCACHE_OSS_BUCKET -ErrorAction SilentlyContinue Remove-Item Env:SCCACHE_OSS_ENDPOINT -ErrorAction SilentlyContinue Remove-Item Env:SCCACHE_OSS_KEY_PREFIX -ErrorAction SilentlyContinue sccache "C:\Users\DSK\.rustup\toolchains\stable-x86_64-pc-windows-msvc\bin\rustc.exe" -vV sccache --show-stats ``` 如果需要排查 sccache server 状态: ```bash sccache --show-stats sccache --stop-server sccache --start-server ``` `sccache --stop-server` 本身也可能因为 server 通道已损坏而失败;只有确认当前没有 `cargo`、`rustc`、`link` 进程后,才用 `taskkill /F /IM sccache.exe /T` 清理残留进程。此时不应阻断本地开发 publish,先使用 wrapper 降级完成验证。 ## 验证 1. `bash -n scripts/dev-rust-stack.sh` 2. 冷启动后直接执行 `cargo check -p api-server`,确认不再出现 `Timed out waiting for server startup`。 3. 执行 `cargo check -p spacetime-module`,确认 proc-macro 依赖和 SpacetimeDB module 都能在 sccache wrapper 下通过。 4. `sccache --show-stats` 显示 `Cache location oss, name: genarrative-sccache`,确认仍在使用 sccache/OSS 缓存。 5. 重新运行 `npm run dev:rust`,确认 publish 命令带有 `--build-options="--debug"`。