92 lines
2.4 KiB
Bash
Executable File
92 lines
2.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
API_URL="${API_URL:-http://127.0.0.1:8080}"
|
|
TMP_DIR="$(mktemp -d)"
|
|
trap 'rm -rf "$TMP_DIR"' EXIT
|
|
|
|
req_json() {
|
|
local path="$1"
|
|
local out_file="$2"
|
|
local code
|
|
local total
|
|
local metrics
|
|
metrics="$(curl -sS --max-time 6 -o "$out_file" -w "%{http_code} %{time_total}" "${API_URL}${path}")"
|
|
code="${metrics%% *}"
|
|
total="${metrics#* }"
|
|
if [[ "$code" != "200" ]]; then
|
|
echo "[vpn_locations] ${path} -> HTTP ${code}" >&2
|
|
cat "$out_file" >&2 || true
|
|
return 1
|
|
fi
|
|
printf "%s\n" "$total"
|
|
}
|
|
|
|
echo "[vpn_locations] API_URL=${API_URL}"
|
|
|
|
# Trigger background refresh (handler must respond immediately from cache/SWR path).
|
|
t1="$(req_json "/api/v1/vpn/locations?refresh=1" "$TMP_DIR/refresh.json")"
|
|
echo "[vpn_locations] refresh request time=${t1}s"
|
|
|
|
# Read current state snapshot.
|
|
t2="$(req_json "/api/v1/vpn/locations" "$TMP_DIR/state.json")"
|
|
echo "[vpn_locations] snapshot request time=${t2}s"
|
|
|
|
python3 - "$TMP_DIR/state.json" <<'PY'
|
|
import json
|
|
import sys
|
|
|
|
path = sys.argv[1]
|
|
with open(path, "r", encoding="utf-8") as f:
|
|
data = json.load(f)
|
|
|
|
required = ("locations", "stale", "refresh_in_progress")
|
|
for k in required:
|
|
if k not in data:
|
|
raise SystemExit(f"[vpn_locations] missing key: {k}")
|
|
|
|
if not isinstance(data["locations"], list):
|
|
raise SystemExit("[vpn_locations] locations must be array")
|
|
if not isinstance(data["stale"], bool):
|
|
raise SystemExit("[vpn_locations] stale must be bool")
|
|
if not isinstance(data["refresh_in_progress"], bool):
|
|
raise SystemExit("[vpn_locations] refresh_in_progress must be bool")
|
|
|
|
print(
|
|
"[vpn_locations] keys OK:",
|
|
f"count={len(data['locations'])}",
|
|
f"stale={data['stale']}",
|
|
f"refresh_in_progress={data['refresh_in_progress']}",
|
|
)
|
|
PY
|
|
|
|
# Poll short window: refresh should eventually finish or provide retry metadata.
|
|
ok=0
|
|
for _ in $(seq 1 12); do
|
|
req_json "/api/v1/vpn/locations" "$TMP_DIR/poll.json" >/dev/null
|
|
if python3 - "$TMP_DIR/poll.json" <<'PY'
|
|
import json
|
|
import sys
|
|
with open(sys.argv[1], "r", encoding="utf-8") as f:
|
|
data = json.load(f)
|
|
if not data.get("refresh_in_progress", False):
|
|
raise SystemExit(0)
|
|
if data.get("next_retry_at"):
|
|
raise SystemExit(0)
|
|
raise SystemExit(1)
|
|
PY
|
|
then
|
|
ok=1
|
|
break
|
|
fi
|
|
sleep 1
|
|
done
|
|
|
|
if [[ "$ok" != "1" ]]; then
|
|
echo "[vpn_locations] refresh state did not settle in expected window" >&2
|
|
cat "$TMP_DIR/poll.json" >&2 || true
|
|
exit 1
|
|
fi
|
|
|
|
echo "[vpn_locations] SWR checks passed"
|