Files
Genarrative/docs/technical/SPACETIMEDB_PUBLISH_SCCACHE_FALLBACK_2026-05-09.md

6.7 KiB
Raw Permalink Blame History

SpacetimeDB publish sccache 降级处理

背景

Windows 本地执行 npm run dev:rustspacetime 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_WRAPPERCargo 仍会先执行 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-sccacheSCCACHE_OSS_ENDPOINT=https://oss-rg-china-mainland.aliyuncs.comSCCACHE_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:4226SYN_SENT,没有真正的 LISTEN,说明当时 client 正在等一个尚未成功监听的 daemon。
  3. 在子进程中临时清掉 SCCACHE_OSS_* 并设置本地 SCCACHE_DIRsccache 退回本地磁盘缓存,日志显示 Init disk cache ...rustc -vVsccache --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 本身可用:

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_derivespacetimedb-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 通道已损坏而失败;只有确认当前没有 cargorustclink 进程后,才用 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"