mirror of
https://github.com/ZoneMinder/zoneminder.git
synced 2026-09-14 22:27:08 -04:00
zmwatch slept 30 seconds before its first pass. The reason is real: when it starts, zmc has not necessarily created its shared memory or written a heartbeat, and neither state is distinguishable from a camera that has died, so the first pass would restart every monitor. A fixed sleep is the wrong shape for that. It is not derived from anything -- ZM_WATCH_CHECK_INTERVAL is 10 and ZM_WATCH_MAX_DELAY is 45, so the delay was three check intervals and shorter than the staleness threshold it was standing in for. On a busy host with many cameras, or one camera slow to answer, 30 seconds is not enough and the fleet gets restarted anyway. It also blocks every other check, and makes running zmwatch by hand a 30 second wait. Each monitor now gets until ZM_WATCH_MAX_DELAY after zmwatch started -- the same threshold used to judge a heartbeat stale -- to appear, and only if we have never yet seen it healthy. Once seen healthy it is judged immediately, so a camera that dies later is caught exactly as fast as before, and every check other than the restart runs from the first pass. Verified against the two monitors on a machine with no daemons running, which is the boot state, with Monitor::control stubbed so nothing was actually started. Before: both monitors restarted on the first pass after the sleep, and again every 10 seconds. After: no restart for 45 seconds, then both restarted on the first pass past the grace, at 50 seconds. So a monitor that never comes up is still caught, ~20 seconds later than before at boot and at the same speed as before thereafter. Also adds ZoneMinder::General::startedInteractively and uses it to skip the start delay in zmstats.pl and zmfilter.pl when a person ran them. zmdc.pl reopens STDIN on /dev/null for everything it starts, so a terminal on STDIN reliably means a hand-run; zmtelemetry.pl already relies on this. A run from cron or a unit file has no terminal either and still waits, which is the right way round. zmstats keeps a delay because it is polite while zmc and zma are competing for the machine, but nothing in it races with startup -- it connects to the database first and has its own reconnect loop -- so the value is now 5 rather than 30. Note zmfilter's existing guard is inverted with respect to that intent: zmpkg starts it as "--filter_id=N --daemon", and the guard skips the delay when a filter is named, so the daemon path never waited and only a manual scan-all did. Left as it is here beyond adding the interactive case; worth a separate look. The zmstats and zmfilter changes are not runtime tested. Running either against a live install prunes and rewrites rows, and there was no throwaway install to point them at; startedInteractively is verified directly in both directions, and all three generated scripts pass perl -Tc. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015Y6FieTwEXuLhhR4e2yiax