unrip/scripts/dev/operator-dashboard-dev.sh
philipp fb547f24d9
All checks were successful
deploy / deploy (push) Successful in 48s
fix: scope inventory fetch by submission time window to prevent OOM
Instead of fetching up to 50k inventory snapshots (~442MB), scope the
query to only the time range of the current submission batch with a
15-minute buffer. For a typical 1-hour batch this drops from 50k rows
to ~300 rows, well within the 1280Mi pod memory limit.

The coalesced_at_idx on intent_inventory_snapshots covers the BETWEEN
clause so this remains efficient.

Proof: history-writer OOM kills from refreshQuoteOutcomes inventory fetch
Assumptions: 15min buffer covers the attribution window for all submissions
Still fake: heuristic gap outcomes may attribute trades imprecisely
2026-06-16 17:17:19 +02:00

97 lines
3.9 KiB
Bash
Executable file

#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
PLATFORM_REPO_DIR="${PLATFORM_REPO_DIR:-$ROOT_DIR/../unrip3}"
KUBECONFIG_PATH="${KUBECONFIG_PATH:-${KUBECONFIG:-$PLATFORM_REPO_DIR/.state/hetzner/kubeconfig.yaml}}"
NAMESPACE="${OPERATOR_DASHBOARD_DEV_NAMESPACE:-unrip}"
SERVICE_NAME="${OPERATOR_DASHBOARD_DEV_SERVICE:-operator-dashboard}"
UPSTREAM_PORT="${OPERATOR_DASHBOARD_DEV_UPSTREAM_PORT:-18090}"
SERVICE_PORT="${OPERATOR_DASHBOARD_DEV_SERVICE_PORT:-8090}"
DEV_HOST="${OPERATOR_DASHBOARD_DEV_HOST:-0.0.0.0}"
DEV_PORT="${OPERATOR_DASHBOARD_DEV_PORT:-5173}"
USERNAME="${OPERATOR_DASHBOARD_DEV_USERNAME:-admin}"
UPSTREAM_HEALTH_TIMEOUT_SECONDS="${OPERATOR_DASHBOARD_DEV_HEALTH_TIMEOUT_SECONDS:-2}"
EXISTING_UPSTREAM_PROBE_TIMEOUT_SECONDS="${OPERATOR_DASHBOARD_DEV_EXISTING_PORT_TIMEOUT_SECONDS:-0.5}"
UPSTREAM_READY_ATTEMPTS="${OPERATOR_DASHBOARD_DEV_READY_ATTEMPTS:-50}"
UPSTREAM_READY_SLEEP_SECONDS="${OPERATOR_DASHBOARD_DEV_READY_SLEEP_SECONDS:-0.2}"
KUBECTL_REQUEST_TIMEOUT="${OPERATOR_DASHBOARD_DEV_KUBECTL_REQUEST_TIMEOUT:-10s}"
PORT_FORWARD_LOG="${OPERATOR_DASHBOARD_DEV_PORT_FORWARD_LOG:-/tmp/operator-dashboard-dev-port-forward.log}"
if [[ -z "${OPERATOR_DASHBOARD_DEV_BASIC_AUTH_PASSWORD:-}" ]]; then
if ! command -v pass >/dev/null 2>&1; then
echo "pass is required unless OPERATOR_DASHBOARD_DEV_BASIC_AUTH_PASSWORD is set" >&2
exit 1
fi
OPERATOR_DASHBOARD_DEV_BASIC_AUTH_PASSWORD="$(pass unrip/dashboard)"
fi
export OPERATOR_DASHBOARD_DEV_BASIC_AUTH_HEADER="Basic $(printf '%s:%s' "$USERNAME" "$OPERATOR_DASHBOARD_DEV_BASIC_AUTH_PASSWORD" | base64 | tr -d '\n')"
export OPERATOR_DASHBOARD_DEV_UPSTREAM_URL="http://127.0.0.1:${UPSTREAM_PORT}"
export OPERATOR_DASHBOARD_DEV_HOST="$DEV_HOST"
export OPERATOR_DASHBOARD_DEV_PORT="$DEV_PORT"
cleanup() {
if [[ -n "${PORT_FORWARD_SUPERVISOR_PID:-}" ]]; then
pkill -P "$PORT_FORWARD_SUPERVISOR_PID" >/dev/null 2>&1 || true
kill "$PORT_FORWARD_SUPERVISOR_PID" >/dev/null 2>&1 || true
wait "$PORT_FORWARD_SUPERVISOR_PID" >/dev/null 2>&1 || true
fi
}
trap cleanup EXIT INT TERM
maintain_port_forward() {
while true; do
KUBECONFIG="$KUBECONFIG_PATH" kubectl --request-timeout="$KUBECTL_REQUEST_TIMEOUT" port-forward -n "$NAMESPACE" "svc/${SERVICE_NAME}" "${UPSTREAM_PORT}:${SERVICE_PORT}" || true
sleep 1
done
}
upstream_ready() {
local timeout_seconds="${1:-$UPSTREAM_HEALTH_TIMEOUT_SECONDS}"
curl -sf \
--connect-timeout "$timeout_seconds" \
--max-time "$timeout_seconds" \
"${OPERATOR_DASHBOARD_DEV_UPSTREAM_URL}/healthz" >/dev/null 2>&1
}
port_in_use() {
timeout 1 bash -c ":</dev/tcp/127.0.0.1/${UPSTREAM_PORT}" >/dev/null 2>&1
}
if port_in_use; then
if upstream_ready "$EXISTING_UPSTREAM_PROBE_TIMEOUT_SECONDS"; then
echo "reusing existing operator-dashboard upstream on port ${UPSTREAM_PORT}" >&2
else
echo "port ${UPSTREAM_PORT} is already in use but /healthz did not respond; stop the stale port-forward or set OPERATOR_DASHBOARD_DEV_UPSTREAM_PORT" >&2
exit 1
fi
cd "$ROOT_DIR"
exec node_modules/.bin/vite --config vite.operator-dashboard.config.mjs --host "$DEV_HOST" --port "$DEV_PORT"
fi
: >"$PORT_FORWARD_LOG"
maintain_port_forward >>"$PORT_FORWARD_LOG" 2>&1 &
PORT_FORWARD_SUPERVISOR_PID=$!
for _ in $(seq 1 "$UPSTREAM_READY_ATTEMPTS"); do
if upstream_ready; then
break
fi
if grep -q "address already in use" "$PORT_FORWARD_LOG"; then
break
fi
sleep "$UPSTREAM_READY_SLEEP_SECONDS"
done
if ! upstream_ready; then
echo "operator-dashboard upstream did not become ready; see $PORT_FORWARD_LOG" >&2
if grep -q "address already in use" "$PORT_FORWARD_LOG"; then
echo "port ${UPSTREAM_PORT} is already in use; stop the old port-forward or set OPERATOR_DASHBOARD_DEV_UPSTREAM_PORT" >&2
fi
exit 1
fi
cd "$ROOT_DIR"
exec node_modules/.bin/vite --config vite.operator-dashboard.config.mjs --host "$DEV_HOST" --port "$DEV_PORT"