diff --git a/scripts/check-production-ops-guardrails.mjs b/scripts/check-production-ops-guardrails.mjs index 93d81f106..f6f2cf056 100644 --- a/scripts/check-production-ops-guardrails.mjs +++ b/scripts/check-production-ops-guardrails.mjs @@ -277,6 +277,12 @@ const checks = [ reason: 'archive 冷备份空间不足时必须能自动降级为 files 存储格式(不落地本地归档)。', }, + { + file: 'scripts/deploy/production-stdb-publish.sh', + includes: 'timeout waiting for transaction confirmation', + reason: + 'publish 客户端等确认超时不能直接判失败:必须重试同版本 publish 以确认模块是否已生效,避免把生产留在维护态。', + }, { file: 'scripts/deploy/production-stdb-publish.sh', includes: 'restore_runtime_services_before_publish', diff --git a/scripts/deploy/production-stdb-publish.sh b/scripts/deploy/production-stdb-publish.sh index 115cf43cf..37933968d 100644 --- a/scripts/deploy/production-stdb-publish.sh +++ b/scripts/deploy/production-stdb-publish.sh @@ -904,6 +904,34 @@ else echo "[production-stdb-publish] 发布 SpacetimeDB module: ${DATABASE} -> ${SERVER_ALIAS}, root=${SPACETIME_ROOT_DIR}" fi +# 迁移已提交但客户端等确认超时(HTTP 504 / timeout waiting for transaction confirmation) +# 时不能直接判失败:重试一次同版本 publish,SpacetimeDB 对已生效的同版本是幂等的 no-op, +# 重试成功即说明目标模块已在位,避免把生产留在维护态。 +run_spacetime_publish() { + local attempt=1 + local output="" + local status=0 + while :; do + output="" + status=0 + if [[ -n "${RUN_AS_USER}" && "$(id -u)" -eq 0 ]]; then + output="$(runuser -u "${RUN_AS_USER}" -- spacetime "${PUBLISH_ARGS[@]}" 2>&1)" || status=$? + else + output="$(spacetime "${PUBLISH_ARGS[@]}" 2>&1)" || status=$? + fi + printf '%s\n' "${output}" + if [[ "${status}" -eq 0 ]]; then + return 0 + fi + if [[ "${attempt}" -ge 2 || "${output}" != *"timeout waiting for transaction confirmation"* ]]; then + return "${status}" + fi + echo "[production-stdb-publish] publish 客户端等事务确认超时,可能迁移已提交;重试一次同版本 publish 以确认模块状态。" >&2 + attempt=$((attempt + 1)) + sleep 5 + done +} + if [[ -n "${RUN_AS_USER}" && "$(id -u)" -eq 0 ]]; then if ! id "${RUN_AS_USER}" >/dev/null 2>&1; then echo "[production-stdb-publish] 发布用户不存在: ${RUN_AS_USER}" >&2 @@ -931,10 +959,10 @@ if [[ -n "${RUN_AS_USER}" && "$(id -u)" -eq 0 ]]; then PUBLISH_ARGS+=(--server "${SERVER_ALIAS}") fi PUBLISH_STARTED=1 - runuser -u "${RUN_AS_USER}" -- spacetime "${PUBLISH_ARGS[@]}" + run_spacetime_publish else PUBLISH_STARTED=1 - spacetime "${PUBLISH_ARGS[@]}" + run_spacetime_publish fi RUNTIME_SERVICE_BOOTSTRAP_SECRET_DIR="$(dirname "${RUNTIME_SERVICE_BOOTSTRAP_SECRET_FILE}")"