fix memory usage redis

This commit is contained in:
Mateusz Gruszczyński
2026-08-16 22:43:06 +02:00
parent 40474cdc59
commit 074d17be89
22 changed files with 1377 additions and 382 deletions
+40 -7
View File
@@ -10,7 +10,27 @@ from app.store import AlertStore
class AnalyticsCacheTests(unittest.TestCase):
def test_refresh_persists_all_dashboard_windows_in_history_cache(self):
def test_archive_and_snapshot_workers_start_and_stop_independently(self):
with tempfile.TemporaryDirectory() as td:
store = AlertStore(os.path.join(td, "ids.db"))
history = TrafficHistory("", retention_hours=24, max_events=1000, memory_events=1000)
cache = AnalyticsSnapshotCache(
store,
history,
threading.Event(),
interval_seconds=15,
archive_interval_seconds=1,
)
cache.start()
time.sleep(0.05)
self.assertTrue(cache._archive_thread.is_alive())
self.assertTrue(cache._snapshot_thread.is_alive())
cache.stop(timeout=0.5)
self.assertFalse(cache._archive_thread.is_alive())
self.assertFalse(cache._snapshot_thread.is_alive())
store.close()
def test_refresh_persists_all_dashboard_windows_in_sqlite_cache(self):
with tempfile.TemporaryDirectory() as td:
store = AlertStore(os.path.join(td, "ids.db"))
history = TrafficHistory("", retention_hours=24, max_events=1000, memory_events=1000)
@@ -21,10 +41,10 @@ class AnalyticsCacheTests(unittest.TestCase):
self.assertEqual({row["window_seconds"] for row in status["persisted"]}, set(SUMMARY_WINDOWS))
snapshot = cache.get(900)
self.assertEqual(snapshot["events"], 1)
self.assertEqual(snapshot["snapshot_source"], "redis-cache")
self.assertEqual(snapshot["snapshot_source"], "sqlite-snapshot")
store.close()
def test_legacy_sqlite_snapshot_is_not_used_for_dashboard_history(self):
def test_refresh_replaces_stale_sqlite_snapshot_with_current_analytics(self):
with tempfile.TemporaryDirectory() as td:
store = AlertStore(os.path.join(td, "ids.db"))
history = TrafficHistory("", retention_hours=24, max_events=1000, memory_events=1000)
@@ -35,13 +55,12 @@ class AnalyticsCacheTests(unittest.TestCase):
self.assertIsNotNone(snapshot)
self.assertEqual(snapshot["events"], 0)
# The in-memory backend is test/dev-only, so it intentionally marks
# analytics incomplete. The important regression is that SQLite's
# stale value is not selected as the dashboard snapshot.
# analytics incomplete. refresh_all must replace the stale snapshot.
self.assertFalse(snapshot["analytics_complete"])
self.assertEqual(snapshot["snapshot_source"], "redis-cache")
self.assertEqual(snapshot["snapshot_source"], "sqlite-snapshot")
# Old SQLite traffic snapshots may exist after an upgrade, but they
# are no longer a data source for the dashboard.
self.assertEqual(store.traffic_snapshot(900)["events"], 7)
self.assertEqual(store.traffic_snapshot(900)["events"], 0)
store.close()
def test_clear_traffic_snapshots_removes_persisted_windows(self):
@@ -53,6 +72,20 @@ class AnalyticsCacheTests(unittest.TestCase):
self.assertEqual(store.traffic_snapshot_status()["windows"], [])
store.close()
def test_arbitrary_five_hour_window_is_not_rounded_to_six_hours(self):
with tempfile.TemporaryDirectory() as td:
store = AlertStore(os.path.join(td, "ids.db"))
history = TrafficHistory("", retention_hours=24, max_events=1000, memory_events=1000)
now = int(time.time() * 1000)
history.add({"id":"inside","ts_ms":now - 4 * 3600 * 1000,"timestamp":"x","type":"flow","direction":"outbound","src_ip":"10.0.0.2","dest_ip":"1.1.1.1","bytes":10})
history.add({"id":"outside","ts_ms":now - int(5.5 * 3600 * 1000),"timestamp":"x","type":"flow","direction":"outbound","src_ip":"10.0.0.2","dest_ip":"1.1.1.1","bytes":10})
cache = AnalyticsSnapshotCache(store, history, threading.Event(), interval_seconds=60)
cache.refresh_windows((18000,))
snapshot = cache.get(18000)
self.assertEqual(snapshot["window_seconds"], 18000)
self.assertEqual(snapshot["events"], 1)
store.close()
if __name__ == "__main__":
unittest.main()