initial: import DOLPHIN baseline 2026-04-21 from dolphinng5_predict working tree
Includes core prod + GREEN/BLUE subsystems: - prod/ (BLUE harness, configs, scripts, docs) - nautilus_dolphin/ (GREEN Nautilus-native impl + dvae/ preserved) - adaptive_exit/ (AEM engine + models/bucket_assignments.pkl) - Observability/ (EsoF advisor, TUI, dashboards) - external_factors/ (EsoF producer) - mc_forewarning_qlabs_fork/ (MC regime/envelope) Excludes runtime caches, logs, backups, and reproducible artifacts per .gitignore.
This commit is contained in:
112
prod/start_exf.sh
Executable file
112
prod/start_exf.sh
Executable file
@@ -0,0 +1,112 @@
|
||||
#!/bin/bash
|
||||
# ExF Fetcher Startup Script
|
||||
# ==========================
|
||||
# Starts the External Factors fetcher daemon for unattended operation.
|
||||
#
|
||||
# Usage:
|
||||
# ./start_exf.sh # Start daemon
|
||||
# ./start_exf.sh stop # Stop daemon
|
||||
# ./start_exf.sh status # Check status
|
||||
# ./start_exf.sh restart # Restart daemon
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
LOG_FILE="/var/log/exf_fetcher.log"
|
||||
PID_FILE="/var/run/exf_fetcher.pid"
|
||||
WARMUP_SECONDS="${EXF_WARMUP:-15}"
|
||||
|
||||
case "${1:-start}" in
|
||||
start)
|
||||
if [ -f "$PID_FILE" ] && kill -0 "$(cat "$PID_FILE")" 2>/dev/null; then
|
||||
echo "ExF fetcher already running (PID: $(cat "$PID_FILE"))"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Starting ExF fetcher daemon..."
|
||||
cd "$SCRIPT_DIR" || exit 1
|
||||
|
||||
nohup python exf_fetcher_flow.py --warmup "$WARMUP_SECONDS" >> "$LOG_FILE" 2>&1 &
|
||||
echo $! > "$PID_FILE"
|
||||
|
||||
echo "ExF fetcher started with PID: $(cat "$PID_FILE")"
|
||||
echo "Logs: tail -f $LOG_FILE"
|
||||
|
||||
# Wait and verify
|
||||
sleep 5
|
||||
if kill -0 "$(cat "$PID_FILE")" 2>/dev/null; then
|
||||
echo "✓ Process is running"
|
||||
else
|
||||
echo "✗ Process failed to start (check logs)"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
|
||||
stop)
|
||||
if [ -f "$PID_FILE" ]; then
|
||||
PID=$(cat "$PID_FILE")
|
||||
if kill -0 "$PID" 2>/dev/null; then
|
||||
echo "Stopping ExF fetcher (PID: $PID)..."
|
||||
kill "$PID"
|
||||
sleep 2
|
||||
if kill -0 "$PID" 2>/dev/null; then
|
||||
echo "Force killing..."
|
||||
kill -9 "$PID"
|
||||
fi
|
||||
echo "✓ Stopped"
|
||||
else
|
||||
echo "ExF fetcher not running"
|
||||
fi
|
||||
rm -f "$PID_FILE"
|
||||
else
|
||||
echo "No PID file found"
|
||||
fi
|
||||
;;
|
||||
|
||||
restart)
|
||||
$0 stop
|
||||
sleep 2
|
||||
$0 start
|
||||
;;
|
||||
|
||||
status)
|
||||
if [ -f "$PID_FILE" ]; then
|
||||
PID=$(cat "$PID_FILE")
|
||||
if kill -0 "$PID" 2>/dev/null; then
|
||||
echo "ExF fetcher is running (PID: $PID)"
|
||||
ps -p "$PID" -o pid,etime,cmd
|
||||
|
||||
# Check Hazelcast
|
||||
echo ""
|
||||
echo "Checking Hazelcast data..."
|
||||
python3 << 'PYEOF'
|
||||
import sys
|
||||
sys.path.insert(0, '/mnt/dolphinng5_predict')
|
||||
try:
|
||||
import hazelcast, json
|
||||
client = hazelcast.HazelcastClient(cluster_name="dolphin", cluster_members=["localhost:5701"], connection_timeout=3.0)
|
||||
data = client.get_map("DOLPHIN_FEATURES").blocking().get("exf_latest")
|
||||
if data:
|
||||
parsed = json.loads(data)
|
||||
print(f" ✓ Data flowing: {parsed.get('_ok_count', 0)} indicators")
|
||||
print(f" ✓ Last push: {parsed.get('_pushed_at', 'N/A')}")
|
||||
client.shutdown()
|
||||
except Exception as e:
|
||||
print(f" ✗ Error: {e}")
|
||||
PYEOF
|
||||
else
|
||||
echo "ExF fetcher not running (stale PID file)"
|
||||
rm -f "$PID_FILE"
|
||||
fi
|
||||
else
|
||||
echo "ExF fetcher not running"
|
||||
fi
|
||||
;;
|
||||
|
||||
logs)
|
||||
tail -f "$LOG_FILE"
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|restart|status|logs}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
Reference in New Issue
Block a user