diff --git a/edge/daemon.py b/edge/daemon.py index 408892b..7bd04a3 100644 --- a/edge/daemon.py +++ b/edge/daemon.py @@ -13,18 +13,21 @@ def run_loop(runtime, client, queue, *, clock, sleep, iterations=None, counters["frames"] += 1 except Exception: counters["errors"] += 1 - if sync_every and i % sync_every == 0: - cfg = client.fetch_config() - if cfg is not None: - from edge.zones import zones_from_config - runtime.apply_zones(zones_from_config(cfg)) - counters["syncs"] += 1 - if heartbeat_every and i % heartbeat_every == 0: - if client.send_heartbeat({"fps": 0.0, "frames": counters["frames"]}): - counters["beats"] += 1 - if flush_every and i % flush_every == 0: - queue.flush() - counters["flushes"] += 1 + try: + if sync_every and i % sync_every == 0: + cfg = client.fetch_config() + if cfg is not None: + from edge.zones import zones_from_config + runtime.apply_zones(zones_from_config(cfg)) + counters["syncs"] += 1 + if heartbeat_every and i % heartbeat_every == 0: + if client.send_heartbeat({"fps": 0.0, "frames": counters["frames"]}): + counters["beats"] += 1 + if flush_every and i % flush_every == 0: + queue.flush() + counters["flushes"] += 1 + except Exception: + counters["errors"] += 1 if frame_interval: sleep(frame_interval) return counters diff --git a/tests/test_daemon.py b/tests/test_daemon.py index 1a675be..2d01880 100644 --- a/tests/test_daemon.py +++ b/tests/test_daemon.py @@ -41,3 +41,16 @@ def test_loop_survives_step_exception(): sync_every=99, heartbeat_every=99, flush_every=99) assert rt.steps == 3 # kept going past the exception assert counters["errors"] == 1 + + +def test_loop_survives_flush_exception(): + class BoomQueue(_Queue): + def flush(self): + self.flushes += 1 + raise RuntimeError("db locked") + rt = _Runtime() + counters = run_loop(rt, _Client(), BoomQueue(), clock=lambda: 0.0, + sleep=lambda s: None, iterations=5, + sync_every=99, heartbeat_every=99, flush_every=2) + assert rt.steps == 5 # loop kept running past the flush exceptions + assert counters["errors"] >= 1