1
This commit is contained in:
@@ -195,7 +195,7 @@ is_spacetime_ready() {
|
||||
local server="$1"
|
||||
local output
|
||||
|
||||
if output="$(spacetime server ping "${server}" 2>&1)" &&
|
||||
if output="$(spacetime --root-dir="${SPACETIME_ROOT_DIR}" server ping "${server}" 2>&1)" &&
|
||||
[[ "${output}" == *"Server is online:"* ]]; then
|
||||
return 0
|
||||
fi
|
||||
@@ -345,6 +345,48 @@ prepare_migration_bootstrap_secret() {
|
||||
echo "[dev:rust] 迁移引导密钥: ${MIGRATION_BOOTSTRAP_SECRET}"
|
||||
}
|
||||
|
||||
is_sccache_wrapper_failure_log() {
|
||||
local log_file="$1"
|
||||
|
||||
grep -Eiq \
|
||||
'sccache: error|could not execute process.*sccache|Failed to send data to or receive data from server|Mismatch of client/server versions|Failed to read response header|failed to fill whole buffer' \
|
||||
"${log_file}"
|
||||
}
|
||||
|
||||
run_spacetime_publish_with_sccache_fallback() {
|
||||
local root_dir="$1"
|
||||
shift
|
||||
|
||||
local publish_log
|
||||
publish_log="$(mktemp -t genarrative-spacetime-publish.XXXXXX.log)"
|
||||
|
||||
set +e
|
||||
spacetime --root-dir="${root_dir}" "$@" 2> >(tee "${publish_log}" >&2)
|
||||
local publish_status="$?"
|
||||
set -e
|
||||
|
||||
if [[ "${publish_status}" -eq 0 ]]; then
|
||||
rm -f "${publish_log}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if ! is_sccache_wrapper_failure_log "${publish_log}"; then
|
||||
rm -f "${publish_log}"
|
||||
return "${publish_status}"
|
||||
fi
|
||||
|
||||
echo "[dev:rust] 检测到 sccache wrapper 通信异常,改用 rustc 直连重试 SpacetimeDB 发布。"
|
||||
echo "[dev:rust] 这只影响本次 publish;项目级 sccache 配置不会被修改。"
|
||||
|
||||
set +e
|
||||
RUSTC_WRAPPER= CARGO_BUILD_RUSTC_WRAPPER= spacetime --root-dir="${root_dir}" "$@"
|
||||
publish_status="$?"
|
||||
set -e
|
||||
|
||||
rm -f "${publish_log}"
|
||||
return "${publish_status}"
|
||||
}
|
||||
|
||||
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd -- "${SCRIPT_DIR}/.." && pwd)"
|
||||
SERVER_RS_DIR="${REPO_ROOT}/server-rs"
|
||||
@@ -564,6 +606,7 @@ if [[ "${SKIP_SPACETIME}" -ne 1 ]]; then
|
||||
# 当目标端口被占用时,SpacetimeDB 会询问是否使用最近的可用端口;
|
||||
# 这里直接发送回车接受默认建议,再从启动日志解析实际监听端口。
|
||||
printf '\n' | spacetime \
|
||||
--root-dir="${SPACETIME_ROOT_DIR}" \
|
||||
start \
|
||||
--data-dir "${SPACETIME_DATA_DIR}" \
|
||||
--listen-addr "${SPACETIME_HOST}:${SPACETIME_PORT}" \
|
||||
@@ -601,7 +644,9 @@ if [[ "${SKIP_PUBLISH}" -ne 1 ]]; then
|
||||
cd "${SERVER_RS_DIR}"
|
||||
# spacetime publish 会在内部调用 Cargo;从 server-rs 目录执行,确保读取
|
||||
# server-rs/.cargo/config.toml 中的 sccache/linker 配置,并复用同一套 target 缓存。
|
||||
spacetime "${PUBLISH_ARGS[@]}"
|
||||
# Windows 本地 sccache server 偶发通信异常时,保留 root-dir/target 缓存路径,
|
||||
# 仅对重试子进程清空 Cargo wrapper,避免可选缓存工具阻断真实构建。
|
||||
run_spacetime_publish_with_sccache_fallback "${SPACETIME_ROOT_DIR}" "${PUBLISH_ARGS[@]}"
|
||||
)
|
||||
fi
|
||||
|
||||
|
||||
@@ -37,14 +37,30 @@ loadEnvFile(resolve(repoRoot, '.env'), fileEnv);
|
||||
loadEnvFile(resolve(repoRoot, '.env.local'), fileEnv);
|
||||
loadEnvFile(resolve(repoRoot, '.env.secrets.local'), fileEnv);
|
||||
|
||||
function buildTargetCandidates() {
|
||||
function resolveConfiguredTarget() {
|
||||
if (fileEnv.GENARRATIVE_RUNTIME_SERVER_TARGET) {
|
||||
return fileEnv.GENARRATIVE_RUNTIME_SERVER_TARGET;
|
||||
}
|
||||
|
||||
if (fileEnv.RUST_SERVER_TARGET) {
|
||||
return fileEnv.RUST_SERVER_TARGET;
|
||||
}
|
||||
|
||||
if (fileEnv.GENARRATIVE_API_TARGET) {
|
||||
return fileEnv.GENARRATIVE_API_TARGET;
|
||||
}
|
||||
|
||||
if (fileEnv.GENARRATIVE_API_PORT) {
|
||||
return `http://127.0.0.1:${fileEnv.GENARRATIVE_API_PORT}`;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
function buildFallbackCandidates() {
|
||||
const candidates = [
|
||||
fileEnv.GENARRATIVE_RUNTIME_SERVER_TARGET,
|
||||
fileEnv.RUST_SERVER_TARGET,
|
||||
fileEnv.GENARRATIVE_API_TARGET,
|
||||
`http://127.0.0.1:${fileEnv.GENARRATIVE_API_PORT || '3100'}`,
|
||||
'http://127.0.0.1:8082',
|
||||
'http://127.0.0.1:3100',
|
||||
'http://127.0.0.1:8082',
|
||||
].filter(Boolean);
|
||||
|
||||
return Array.from(new Set(candidates));
|
||||
@@ -70,39 +86,30 @@ async function isTargetReachable(target) {
|
||||
}
|
||||
|
||||
async function resolveRuntimeTarget() {
|
||||
const candidates = buildTargetCandidates();
|
||||
const reachableTargets = [];
|
||||
const configuredTarget = resolveConfiguredTarget();
|
||||
|
||||
for (const target of candidates) {
|
||||
if (await isTargetReachable(target)) {
|
||||
reachableTargets.push(target);
|
||||
if (
|
||||
target === fileEnv.GENARRATIVE_RUNTIME_SERVER_TARGET ||
|
||||
target === fileEnv.RUST_SERVER_TARGET ||
|
||||
target === fileEnv.GENARRATIVE_API_TARGET
|
||||
) {
|
||||
return {
|
||||
target,
|
||||
fallbackUsed: false,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (reachableTargets.length > 0) {
|
||||
if (configuredTarget) {
|
||||
return {
|
||||
target: reachableTargets[0],
|
||||
fallbackUsed: true,
|
||||
target: configuredTarget,
|
||||
fallbackUsed: false,
|
||||
targetUnavailable: !(await isTargetReachable(configuredTarget)),
|
||||
};
|
||||
}
|
||||
|
||||
for (const target of buildFallbackCandidates()) {
|
||||
if (await isTargetReachable(target)) {
|
||||
return {
|
||||
target,
|
||||
fallbackUsed: true,
|
||||
targetUnavailable: false,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
target:
|
||||
fileEnv.GENARRATIVE_RUNTIME_SERVER_TARGET ||
|
||||
fileEnv.RUST_SERVER_TARGET ||
|
||||
fileEnv.GENARRATIVE_API_TARGET ||
|
||||
`http://127.0.0.1:${fileEnv.GENARRATIVE_API_PORT || '3100'}`,
|
||||
target: 'http://127.0.0.1:3100',
|
||||
fallbackUsed: false,
|
||||
targetUnavailable: true,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -113,6 +120,12 @@ if (runtimeTarget.fallbackUsed) {
|
||||
);
|
||||
}
|
||||
|
||||
if (runtimeTarget.targetUnavailable) {
|
||||
console.warn(
|
||||
`[dev:web] Rust target 当前不可用: ${runtimeTarget.target},请先启动 api-server。`,
|
||||
);
|
||||
}
|
||||
|
||||
const mergedEnv = {
|
||||
...fileEnv,
|
||||
RUST_SERVER_TARGET: runtimeTarget.target,
|
||||
|
||||
Reference in New Issue
Block a user