6.7 KiB
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 通信异常或版本残留不一致时,可能出现:
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 代码错误。
辅助证据:
rustc -vV可直接输出版本,说明 Rust 工具链本身可用。tasklist曾只看到sccache --show-stats客户端进程,netstat只出现到127.0.0.1:4226的SYN_SENT,没有真正的LISTEN,说明当时 client 正在等一个尚未成功监听的 daemon。- 在子进程中临时清掉
SCCACHE_OSS_*并设置本地SCCACHE_DIR后,sccache 退回本地磁盘缓存,日志显示Init disk cache ...,rustc -vV和sccache --show-stats均能完成。 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 本身可用:
rustc -vV
如果要保留 sccache 并修复冷启动等待时间,在 PowerShell 中创建或更新 sccache 默认配置:
$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 曾缓存的失败探测结果,并从冷启动验证:
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 中执行:
cd server-rs/crates/spacetime-module
RUSTC_WRAPPER= CARGO_BUILD_RUSTC_WRAPPER= cargo check --target=wasm32-unknown-unknown
PowerShell 原生 Cargo 的一次性 wrapper 绕过命令是:
cd C:\proj\Genarrative\server-rs
cargo check -p api-server --config "build.rustc-wrapper=''"
如果需要验证是否为 OSS/代理冷启动问题,可只在当前 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 状态:
sccache --show-stats
sccache --stop-server
sccache --start-server
sccache --stop-server 本身也可能因为 server 通道已损坏而失败;只有确认当前没有 cargo、rustc、link 进程后,才用 taskkill /F /IM sccache.exe /T 清理残留进程。此时不应阻断本地开发 publish,先使用 wrapper 降级完成验证。
验证
bash -n scripts/dev-rust-stack.sh- 冷启动后直接执行
cargo check -p api-server,确认不再出现Timed out waiting for server startup。 - 执行
cargo check -p spacetime-module,确认 proc-macro 依赖和 SpacetimeDB module 都能在 sccache wrapper 下通过。 sccache --show-stats显示Cache location oss, name: genarrative-sccache,确认仍在使用 sccache/OSS 缓存。- 重新运行
npm run dev:rust,确认 publish 命令带有--build-options="--debug"。