Files
DOLPHIN/prod/scan_bridge_deploy.py

175 lines
5.0 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
"""
DOLPHIN Scan Bridge Prefect Deployment Script
==============================================
Deploy the scan bridge daemon to Prefect.
Usage:
python scan_bridge_deploy.py [create|start|stop|status]
"""
import sys
import subprocess
from pathlib import Path
PROJECT_ROOT = Path(__file__).parent.parent
sys.path.insert(0, str(PROJECT_ROOT))
sys.path.insert(0, str(PROJECT_ROOT / 'nautilus_dolphin'))
DAEMON_POOL = "dolphin-daemon-pool"
DAEMON_NAME = "scan-bridge-daemon"
DAEMON_FILE = "prod/scan_bridge_prefect_daemon.py"
def run_cmd(cmd: list, check: bool = True) -> subprocess.CompletedProcess:
"""Run a command and return result."""
print(f"$ {' '.join(cmd)}")
return subprocess.run(cmd, check=check, capture_output=True, text=True)
def create_deployment():
"""Create the Prefect deployment."""
print("=" * 60)
print("Creating Scan Bridge Prefect Deployment")
print("=" * 60)
# Check if pool exists
result = run_cmd(["prefect", "work-pool", "ls"], check=False)
if DAEMON_POOL not in result.stdout:
print(f"\n📦 Creating work pool: {DAEMON_POOL}")
run_cmd(["prefect", "work-pool", "create", DAEMON_POOL, "--type", "process"])
else:
print(f"\n✅ Work pool exists: {DAEMON_POOL}")
# Build deployment
print(f"\n🔨 Building deployment...")
cmd = [
"prefect", "deployment", "build",
f"{DAEMON_FILE}:scan_bridge_daemon_flow",
"--name", DAEMON_NAME,
"--pool", DAEMON_POOL,
"--output", "scan-bridge-daemon-deployment.yaml"
]
run_cmd(cmd)
# Apply deployment
print(f"\n🚀 Applying deployment...")
run_cmd(["prefect", "deployment", "apply", "scan-bridge-daemon-deployment.yaml"])
print("\n" + "=" * 60)
print("✅ Deployment created!")
print("=" * 60)
print(f"\nTo start the daemon:")
print(f" python scan_bridge_deploy.py start")
print(f"\nOr manually:")
print(f" prefect deployment run 'scan-bridge-daemon/scan-bridge-daemon'")
print(f" prefect worker start --pool {DAEMON_POOL}")
def start_worker():
"""Start the Prefect worker for the daemon pool."""
print("=" * 60)
print("Starting Prefect Worker")
print("=" * 60)
print(f"\nPool: {DAEMON_POOL}")
print("Press Ctrl+C to stop\n")
try:
subprocess.run(["prefect", "worker", "start", "--pool", DAEMON_POOL])
except KeyboardInterrupt:
print("\n\n👋 Worker stopped")
def check_status():
"""Check deployment status."""
print("=" * 60)
print("Scan Bridge Prefect Status")
print("=" * 60)
# List deployments
print("\n📋 Deployments:")
result = run_cmd(["prefect", "deployment", "ls"], check=False)
if DAEMON_NAME in result.stdout:
for line in result.stdout.split('\n'):
if DAEMON_NAME in line:
print(f" {line}")
else:
print(" ❌ No deployment found")
# List work pools
print("\n🏊 Work Pools:")
result = run_cmd(["prefect", "work-pool", "ls"], check=False)
if DAEMON_POOL in result.stdout:
for line in result.stdout.split('\n'):
if DAEMON_POOL in line:
print(f" {line}")
else:
print(f" ❌ Pool '{DAEMON_POOL}' not found")
# Check flow runs
print("\n🔄 Recent Flow Runs:")
result = run_cmd(["prefect", "flow-run", "ls", "--limit", "5"], check=False)
if result.stdout:
print(result.stdout)
def quick_health_check():
"""Run standalone health check."""
print("=" * 60)
print("Scan Bridge Health Check")
print("=" * 60)
import sys
sys.path.insert(0, '/mnt/dolphinng5_predict/prod')
from scan_bridge_prefect_daemon import quick_health_check as check
result = check()
print("\n" + "=" * 60)
status = result.get("status", "unknown")
age = result.get("age_sec", 0)
if status == "healthy":
print(f"✅ HEALTHY: Data age {age:.0f}s")
elif status == "warning":
print(f"⚠️ WARNING: Data age {age:.0f}s")
elif status == "stale":
print(f"❌ STALE: Data age {age:.0f}s")
else:
print(f"❌ ERROR: {status}")
def main():
import argparse
parser = argparse.ArgumentParser(
description="Deploy and manage Scan Bridge Prefect daemon"
)
parser.add_argument(
"action",
choices=["create", "start", "stop", "status", "health"],
default="status",
nargs="?",
help="Action to perform"
)
args = parser.parse_args()
if args.action == "create":
create_deployment()
elif args.action == "start":
start_worker()
elif args.action == "status":
check_status()
elif args.action == "health":
quick_health_check()
elif args.action == "stop":
print("To stop: Press Ctrl+C in the worker terminal")
print("Or: pkill -f 'prefect worker'")
else:
parser.print_help()
if __name__ == "__main__":
main()