feat(run): startup + shutdown ping on both channels
Answers 'is it even running?' within seconds of 'atm run' — no waiting 30 min for heartbeat + no need for a live trigger to occur. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -282,6 +282,16 @@ def run_live(cfg, duration_s=None, capture_stub: bool = False) -> None:
|
||||
]
|
||||
notifier = FanoutNotifier(backends, Path(cfg.dead_letter_path))
|
||||
|
||||
# Startup ping — confirms both channels work before the first bar closes.
|
||||
from datetime import datetime
|
||||
dur_note = f" duration={cfg.heartbeat_min:d}m heartbeat" if duration_s is None else f" duration={duration_s/3600:.2f}h"
|
||||
notifier.send(Alert(
|
||||
kind="heartbeat",
|
||||
title="ATM started",
|
||||
body=f"config={cfg.config_version}{dur_note} at {datetime.now().isoformat(timespec='seconds')}",
|
||||
))
|
||||
audit.log({"event": "started", "config": cfg.config_version})
|
||||
|
||||
start = time.monotonic()
|
||||
heartbeat_due = start + cfg.heartbeat_min * 60
|
||||
levels_extractor = None
|
||||
@@ -337,6 +347,13 @@ def run_live(cfg, duration_s=None, capture_stub: bool = False) -> None:
|
||||
heartbeat_due = time.time() + cfg.heartbeat_min * 60
|
||||
time.sleep(cfg.loop_interval_s)
|
||||
finally:
|
||||
try:
|
||||
notifier.send(Alert(
|
||||
kind="heartbeat", title="ATM stopped",
|
||||
body=f"after {time.monotonic() - start:.0f}s",
|
||||
))
|
||||
except Exception:
|
||||
pass
|
||||
notifier.stop()
|
||||
audit.close()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user