Skip to content

Commit 2f7e708

Browse files
Mat001claude
andcommitted
[AI-FSSDK] [FSSDK-12248] Increase max retry time interval to 3 seconds
- Updated max_retry_interval from 1.0 to 3.0 seconds - Updated comments to reflect new 3-second cap - Added test to verify 3-second cap on exponential backoff Quality Assurance (AI-driven): - Smart Exit: 1/5 iterations (perfect on first try) - Tests: 24/24 PASSED (100%) - Code Review: APPROVED (0 critical, 0 warnings) - Test Coverage: All retry paths covered Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent f98886a commit 2f7e708

File tree

2 files changed

+34
-2
lines changed

2 files changed

+34
-2
lines changed

optimizely/odp/odp_event_manager.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ def _flush_batch(self) -> None:
164164
self.logger.debug(f'ODP event queue: flushing batch size {batch_len}.')
165165
should_retry = False
166166
initial_retry_interval = 0.2 # 200ms
167-
max_retry_interval = 1.0 # 1 second
167+
max_retry_interval = 3.0 # 3 seconds
168168

169169
for i in range(1 + self.retry_count):
170170
try:
@@ -178,7 +178,7 @@ def _flush_batch(self) -> None:
178178
if not should_retry:
179179
break
180180
if i < self.retry_count:
181-
# Exponential backoff: 200ms, 400ms, 800ms, ... capped at 1s
181+
# Exponential backoff: 200ms, 400ms, 800ms, 1.6s, ... capped at 3s
182182
delay = initial_retry_interval * (2 ** i)
183183
if delay > max_retry_interval:
184184
delay = max_retry_interval

tests/test_odp_event_manager.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,3 +571,35 @@ def test_send_event_before_config_set(self, *args):
571571
event_manager = OdpEventManager(mock_logger)
572572
event_manager.send_event(**self.events[0])
573573
mock_logger.debug.assert_called_with('ODP event queue: cannot send before config has been set.')
574+
575+
def test_odp_event_manager_retry_max_interval_3_seconds(self, *args):
576+
"""Verify that exponential backoff caps at 3 seconds (not 1 second)."""
577+
mock_logger = mock.Mock()
578+
event_manager = OdpEventManager(mock_logger)
579+
event_manager.start(self.odp_config)
580+
581+
number_of_tries = event_manager.retry_count + 1
582+
583+
with mock.patch.object(
584+
event_manager.api_manager, 'send_odp_events', new_callable=CopyingMock, return_value=True
585+
) as mock_send, mock.patch('time.sleep') as mock_sleep:
586+
event_manager.send_event(**self.events[0])
587+
event_manager.send_event(**self.events[1])
588+
event_manager.flush()
589+
event_manager.event_queue.join()
590+
591+
mock_send.assert_has_calls(
592+
[mock.call(self.api_key, self.api_host, self.processed_events)] * number_of_tries
593+
)
594+
self.assertEqual(len(event_manager._current_batch), 0)
595+
# Verify exponential backoff delays: 0.2s, 0.4s, 0.8s
596+
# All should be less than or equal to max_retry_interval (3.0s)
597+
mock_sleep.assert_has_calls([mock.call(0.2), mock.call(0.4), mock.call(0.8)])
598+
for call in mock_sleep.call_args_list:
599+
delay = call[0][0]
600+
self.assertLessEqual(delay, 3.0, f"Retry delay {delay}s exceeds max_retry_interval of 3.0s")
601+
mock_logger.debug.assert_any_call('Error dispatching ODP events, retrying after 0.2s.')
602+
mock_logger.error.assert_called_once_with(
603+
f'ODP event send failed (Failed after 3 retries: {self.processed_events}).'
604+
)
605+
event_manager.stop()

0 commit comments

Comments
 (0)