#!/usr/bin/env python3 """start_wr_daemon.py — T21.5 §7: THE canonical daemon restart launcher. T21.4 live finding: `python3 daemon.py` defaults WR_ROOT to the daemon's install dir, so a restart silently opened a second event store. This launcher resolves the root ONCE through scripts/wr_root_resolver.py (the single authority) and passes it explicitly — nobody has to remember to export WR_ROOT. """ from __future__ import annotations import os import subprocess import sys import time import urllib.request from pathlib import Path _SCRIPT_DIR = Path(__file__).resolve().parent sys.path.insert(0, str(_SCRIPT_DIR)) import wr_root_resolver as resolver # noqa: E402 DAEMON_CODE_CANDIDATES = ( "/home/nick/.local/share/mimo-wait-resume/daemon.py", ) def find_daemon_code() -> Path: for cand in DAEMON_CODE_CANDIDATES: p = Path(cand) if p.is_file(): return p raise RuntimeError(f"daemon.py not found in {DAEMON_CODE_CANDIDATES}") def main() -> int: root = resolver.resolve_root() daemon = find_daemon_code() env = dict(os.environ, WR_ROOT=str(root), # daemon data root RUNE_WR_ROOT=str(root), # adapter-side authority RUNE_WR_CODE=str(daemon.parent)) port = sys.argv[1] if len(sys.argv) > 1 else "8791" proc = subprocess.Popen( [sys.executable, str(daemon), port], env=env, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, start_new_session=True) # bounded startup probe (process-local, not an external wait) for _ in range(20): try: with urllib.request.urlopen( f"http://127.0.0.1:{port}/health", timeout=1) as r: if r.status == 200: print(f"wr daemon up: pid={proc.pid} root={root} " f"port={port}") return 0 except OSError: time.sleep(0.25) print(f"wr daemon did not become healthy (pid={proc.pid})", file=sys.stderr) return 1 if __name__ == "__main__": sys.exit(main())