Skip to content

Commit 539cbe3

Browse files
committed
Skip SSE config updated events if they arrive too fast
1 parent 7b1f870 commit 539cbe3

2 files changed

Lines changed: 36 additions & 0 deletions

File tree

aikido_zen/background_process/realtime/listen_for_config_updates.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"""
44

55
import json
6+
import time
67

78
from aikido_zen.helpers.token import Token
89
from aikido_zen.helpers.logging import logger
@@ -26,6 +27,21 @@ def listen_for_config_updates(connection_manager, event_scheduler):
2627

2728
token = connection_manager.token
2829
last_updated_at = connection_manager.conf.last_updated_at
30+
last_config_refresh_started_at = None
31+
32+
def config_update_arrived_too_fast():
33+
nonlocal last_config_refresh_started_at
34+
35+
now = time.monotonic()
36+
if (
37+
last_config_refresh_started_at is not None
38+
and now - last_config_refresh_started_at
39+
< 9
40+
):
41+
return True
42+
43+
last_config_refresh_started_at = now
44+
return False
2945

3046
def on_event(event):
3147
nonlocal last_updated_at
@@ -43,6 +59,10 @@ def on_event(event):
4359
logger.debug("SSE config-updated event has invalid payload: %s", event.data)
4460
return
4561

62+
if config_update_arrived_too_fast():
63+
logger.debug("SSE config-updated event ignored by refresh throttle")
64+
return
65+
4666
logger.debug("SSE config-updated event, fetching new config")
4767

4868
try:

aikido_zen/background_process/realtime/listen_for_config_updates_test.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,22 @@ def test_updates_last_updated_at_so_a_second_stale_event_is_ignored(
188188
mock_get_config.assert_called_once()
189189

190190

191+
def test_throttles_newer_events(connection_manager):
192+
connection_manager.conf.last_updated_at = 100
193+
event_scheduler = make_inline_scheduler()
194+
on_event = get_on_event(connection_manager, event_scheduler)
195+
196+
new_config = {"endpoints": [], "configUpdatedAt": 200}
197+
with patch(
198+
"aikido_zen.background_process.realtime.get_config", return_value=new_config
199+
) as mock_get_config:
200+
on_event(make_event(data={"configUpdatedAt": 200}))
201+
on_event(make_event(data={"configUpdatedAt": 300}))
202+
203+
mock_get_config.assert_called_once_with(connection_manager.token)
204+
connection_manager.update_firewall_lists.assert_called_once()
205+
206+
191207
def test_handles_get_config_failure_gracefully(connection_manager, caplog):
192208
connection_manager.conf.last_updated_at = 100
193209
on_event = get_on_event(connection_manager)

0 commit comments

Comments
 (0)