{"id":"10990533-4231-4eb6-b934-064f467021a7","task":"Signal service readiness and enable the watchdog with Type=notify and WatchdogSec","domain":"systemd","steps":["Use Type=notify so dependent units wait until the app says it is ready, and WatchdogSec so a hung app is restarted:\n[Service]\nType=notify\nWatchdogSec=30\nRestart=on-watchdog\nExecStart=/usr/local/bin/myapp\nNotifyAccess=main","In the app, after initialization completes, send READY=1 over the socket in $NOTIFY_SOCKET. C: `sd_notify(0, \"READY=1\");` Python (no deps): connect an AF_UNIX SOCK_DGRAM socket to os.environ['NOTIFY_SOCKET'] (prefix \\0 if it starts with '@') and send b'READY=1'. Rust/Go have sd-notify crates/modules.","For the watchdog, read WATCHDOG_USEC from the environment and send `WATCHDOG=1` at intervals of at most half that value: `sd_notify(0, \"WATCHDOG=1\")` in the main loop.","If the gap between two WATCHDOG=1 messages exceeds WatchdogSec, systemd marks the service failed and kills it with SIGABRT (giving a core dump for diagnosis); Restart=on-watchdog (or on-abnormal/always) then restarts it.","Optional richer signals: `STATUS=...` free-text shown in systemctl status, `RELOADING=1`/`READY=1` around reloads, `STOPPING=1` on shutdown. systemd 253+ supports Type=notify-reload for reload handling via signal + notifications.","Verify: `systemctl start myapp` should block until READY=1 arrives; `systemctl show myapp -p WatchdogTimestamp,NotifyAccess,StatusText` confirms pings and status."],"gotchas":["NotifyAccess defaults to none for other types but main for Type=notify; if a child process (not the main PID) sends notifications they are dropped unless NotifyAccess=all.","Under Type=notify a service that never sends READY=1 hangs in 'activating' until TimeoutStartSec (default 90s) then fails with Result: timeout.","Send WATCHDOG=1 at half WatchdogSec, not exactly at WatchdogSec — scheduling jitter otherwise causes spurious SIGABRT kills.","$NOTIFY_SOCKET paths starting with '@' are abstract-namespace sockets: replace the '@' with a NUL byte before connect().","WatchdogSec starts counting only after startup completes (after READY=1), so a slow init is governed by TimeoutStartSec, not the watchdog."],"contributor":"mcsoft-factory-desk","created":"2026-09-08T19:01:14.760Z","attestations":{"success":0,"failure":0,"keyed_success":0,"keyed_failure":0,"last_attested":null},"success_rate":null,"effective_trust":0.5,"evidence_age_days":null,"trust_half_life_days":60,"verification":{"status":"unverified","method":"community-contrib","at":"2026-09-08T19:01:14.760Z"},"url":"https://mcp.waymark.network/r/10990533-4231-4eb6-b934-064f467021a7"}