Skip to content

Commit 2853e37

Browse files
authored
Merge pull request #5322 from Agenta-AI/fix-railway-configure-race
ci(railway): retry service resolution to survive the bootstrap→configure race
2 parents 14895df + b46eb2a commit 2853e37

1 file changed

Lines changed: 66 additions & 3 deletions

File tree

hosting/railway/oss/scripts/configure.sh

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,69 @@ _service_id() {
8787
| .serviceInstances.edges[].node | select(.serviceName==$n) | .serviceId][0] // empty' 2>/dev/null || true
8888
}
8989

90+
# _refresh_status_json: re-fetch the cached status snapshot; keep the old one
91+
# if the fetch fails so a transient error cannot blank out working IDs.
92+
_refresh_status_json() {
93+
local fresh
94+
fresh="$(railway_call status --json 2>/dev/null || true)"
95+
[ -n "$fresh" ] && RAILWAY_STATUS_JSON="$fresh"
96+
}
97+
98+
# _service_id_with_retry <service-name> -> serviceId (empty when unresolved).
99+
# A service bootstrap created seconds earlier may not be visible in the status
100+
# snapshot yet (bootstrap→configure eventual-consistency race), so re-fetch the
101+
# snapshot and retry a few times before giving up. First-try hits (the normal
102+
# case) cost zero extra API calls and zero sleeps.
103+
_service_id_with_retry() {
104+
local service="$1" svc_id attempt
105+
local attempts="${RAILWAY_SERVICE_RESOLVE_ATTEMPTS:-6}"
106+
local delay="${RAILWAY_SERVICE_RESOLVE_DELAY:-5}"
107+
108+
for ((attempt = 1; attempt <= attempts; attempt++)); do
109+
svc_id="$(_service_id "$service")"
110+
if [ -n "$svc_id" ]; then
111+
printf '%s' "$svc_id"
112+
return 0
113+
fi
114+
if [ "$attempt" -lt "$attempts" ]; then
115+
printf "Service id for '%s' not in status snapshot yet; re-fetching in %ds (attempt %d/%d)\n" \
116+
"$service" "$delay" "$attempt" "$attempts" >&2
117+
sleep "$delay"
118+
_refresh_status_json
119+
fi
120+
done
121+
# Empty output: the caller falls back to the CLI path.
122+
return 0
123+
}
124+
125+
# _cli_set_vars <service> KEY=VALUE ...
126+
# CLI-path variable set. "Service '<name>' not found" seconds after bootstrap
127+
# created it is the same eventual-consistency race, so retry that specific
128+
# failure a couple of times instead of failing the deploy on the first hit.
129+
# Other failures surface immediately (railway_call already retries transient
130+
# network errors internally).
131+
_cli_set_vars() {
132+
local service="$1"
133+
shift
134+
local attempts="${RAILWAY_CLI_SET_ATTEMPTS:-3}"
135+
local delay="${RAILWAY_SERVICE_RESOLVE_DELAY:-5}"
136+
local try output
137+
138+
for ((try = 1; try <= attempts; try++)); do
139+
if output="$(railway_call variable set --service "$service" --environment "$ENV_NAME" --skip-deploys "$@" 2>&1)"; then
140+
return 0
141+
fi
142+
if [ "$try" -lt "$attempts" ] && printf '%s' "$output" | grep -qi "not found"; then
143+
printf "railway variable set: service '%s' not visible yet, retrying in %ds (attempt %d/%d)\n" \
144+
"$service" "$delay" "$try" "$attempts" >&2
145+
sleep "$delay"
146+
continue
147+
fi
148+
[ -n "$output" ] && printf '%s\n' "$output" >&2
149+
return 1
150+
done
151+
}
152+
90153
# _vars_to_json KEY=VALUE ... -> {"KEY":"VALUE",...} (split on the first '=')
91154
_vars_to_json() {
92155
local json='{}' kv key val
@@ -111,18 +174,18 @@ upsert_service_vars() {
111174
[ "$#" -gt 0 ] || return 0
112175

113176
if [ -z "${RAILWAY_API_TOKEN:-}" ] || [ -z "$RAILWAY_PROJECT_ID" ]; then
114-
railway_call variable set --service "$service" --environment "$ENV_NAME" --skip-deploys "$@" >/dev/null
177+
_cli_set_vars "$service" "$@"
115178
return 0
116179
fi
117180

118181
local svc_id
119-
svc_id="$(_service_id "$service")"
182+
svc_id="$(_service_id_with_retry "$service")"
120183
if [ -z "$svc_id" ]; then
121184
# Name didn't match the cached status JSON (e.g. unexpected casing). Don't
122185
# hard-fail the deploy where the CLI's --service would have worked; fall
123186
# back to it.
124187
printf "Could not resolve service id for '%s'; falling back to CLI variable set.\n" "$service" >&2
125-
railway_call variable set --service "$service" --environment "$ENV_NAME" --skip-deploys "$@" >/dev/null
188+
_cli_set_vars "$service" "$@"
126189
return 0
127190
fi
128191

0 commit comments

Comments
 (0)