Skip to content

Commit b3a36ba

Browse files
authored
Merge pull request #615 from runloopai/alb/long-poll-tests
Add tests for long polling logic
2 parents 3586007 + 26db652 commit b3a36ba

File tree

4 files changed

+903
-18
lines changed

4 files changed

+903
-18
lines changed

src/runloop_api_client/lib/polling.py

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,26 @@
22
from typing import Any, TypeVar, Callable, Optional
33
from dataclasses import dataclass
44

5-
T = TypeVar('T')
5+
T = TypeVar("T")
6+
67

78
@dataclass
89
class PollingConfig:
910
"""Configuration for polling behavior"""
11+
1012
interval_seconds: float = 1.0
1113
max_attempts: int = 120
1214
timeout_seconds: Optional[float] = None
1315

16+
1417
class PollingTimeout(Exception):
1518
"""Raised when polling exceeds max attempts or timeout"""
19+
1620
def __init__(self, message: str, last_value: Any):
1721
self.last_value = last_value
1822
super().__init__(f"{message}. Last retrieved value: {last_value}")
1923

24+
2025
def poll_until(
2126
retriever: Callable[[], T],
2227
is_terminal: Callable[[T], bool],
@@ -25,27 +30,27 @@ def poll_until(
2530
) -> T:
2631
"""
2732
Poll until a condition is met or timeout/max attempts are reached.
28-
33+
2934
Args:
3035
retriever: Callable that returns the object to check
3136
is_terminal: Callable that returns True when polling should stop
3237
config: Optional polling configuration
3338
on_error: Optional error handler that can return a value to continue polling
3439
or re-raise the exception to stop polling
35-
40+
3641
Returns:
3742
The final state of the polled object
38-
43+
3944
Raises:
4045
PollingTimeout: When max attempts or timeout is reached
4146
"""
4247
if config is None:
4348
config = PollingConfig()
44-
49+
4550
attempts = 0
4651
start_time = time.time()
4752
last_result = None
48-
53+
4954
while True:
5055
try:
5156
last_result = retriever()
@@ -54,23 +59,17 @@ def poll_until(
5459
last_result = on_error(e)
5560
else:
5661
raise
57-
62+
5863
if is_terminal(last_result):
5964
return last_result
60-
65+
6166
attempts += 1
6267
if attempts >= config.max_attempts:
63-
raise PollingTimeout(
64-
f"Exceeded maximum attempts ({config.max_attempts})",
65-
last_result
66-
)
67-
68+
raise PollingTimeout(f"Exceeded maximum attempts ({config.max_attempts})", last_result)
69+
6870
if config.timeout_seconds is not None:
6971
elapsed = time.time() - start_time
7072
if elapsed >= config.timeout_seconds:
71-
raise PollingTimeout(
72-
f"Exceeded timeout of {config.timeout_seconds} seconds",
73-
last_result
74-
)
75-
73+
raise PollingTimeout(f"Exceeded timeout of {config.timeout_seconds} seconds", last_result)
74+
7675
time.sleep(config.interval_seconds)

0 commit comments

Comments
 (0)