|
3 | 3 |
|
4 | 4 |
|
5 | 5 | class RetryStrategy(ABC):
|
| 6 | + """Abstract base class that defines the interface for any retry strategy. |
| 7 | +
|
| 8 | + See :obj:`MaxRetries`, :obj:`MaxWaitTime`, and :obj:`RegularPeriodRetry` for |
| 9 | + example implementations. |
| 10 | + """ |
| 11 | + |
6 | 12 | @abstractmethod
|
7 | 13 | def is_done(self) -> bool:
|
| 14 | + """Check if the retry strategy has exhausted its retries.""" |
8 | 15 | pass
|
9 | 16 |
|
10 | 17 | @abstractmethod
|
11 | 18 | def wait(self) -> None:
|
| 19 | + """Delay implementation before the next retry attempt.""" |
12 | 20 | pass
|
13 | 21 |
|
| 22 | + @abstractmethod |
14 | 23 | def step(self) -> None:
|
| 24 | + """Update internal attributes of the retry strategy.""" |
15 | 25 | pass
|
16 | 26 |
|
17 | 27 |
|
18 | 28 | class MaxRetries(RetryStrategy):
|
19 | 29 | """Check for submissions status every 100 ms and retry a maximum of
|
20 |
| - `max_retries` times.""" |
| 30 | + `max_retries` times. |
| 31 | +
|
| 32 | + Parameters |
| 33 | + ---------- |
| 34 | + max_retries : int |
| 35 | + Max number of retries. |
| 36 | + """ |
21 | 37 |
|
22 | 38 | def __init__(self, max_retries: int = 20):
|
| 39 | + if max_retries < 1: |
| 40 | + raise ValueError("max_retries must be at least 1.") |
23 | 41 | self.n_retries = 0
|
24 | 42 | self.max_retries = max_retries
|
25 | 43 |
|
26 | 44 | def step(self):
|
| 45 | + """Increment the number of retries by one.""" |
27 | 46 | self.n_retries += 1
|
28 | 47 |
|
29 | 48 | def wait(self):
|
| 49 | + """Wait for 0.1 seconds between retries.""" |
30 | 50 | time.sleep(0.1)
|
31 | 51 |
|
32 | 52 | def is_done(self) -> bool:
|
| 53 | + """Check if the number of retries is bigger or equal to specified |
| 54 | + maximum number of retries.""" |
33 | 55 | return self.n_retries >= self.max_retries
|
34 | 56 |
|
35 | 57 |
|
36 | 58 | class MaxWaitTime(RetryStrategy):
|
37 | 59 | """Check for submissions status every 100 ms and wait for all submissions
|
38 |
| - a maximum of `max_wait_time` (seconds).""" |
| 60 | + a maximum of `max_wait_time` (seconds). |
| 61 | +
|
| 62 | + Parameters |
| 63 | + ---------- |
| 64 | + max_wait_time_sec : float |
| 65 | + Maximum waiting time (in seconds). |
| 66 | + """ |
39 | 67 |
|
40 | 68 | def __init__(self, max_wait_time_sec: float = 5 * 60):
|
41 | 69 | self.max_wait_time_sec = max_wait_time_sec
|
42 | 70 | self.total_wait_time = 0
|
43 | 71 |
|
44 | 72 | def step(self):
|
| 73 | + """Add 0.1 seconds to total waiting time.""" |
45 | 74 | self.total_wait_time += 0.1
|
46 | 75 |
|
47 | 76 | def wait(self):
|
| 77 | + """Wait (sleep) for 0.1 seconds.""" |
48 | 78 | time.sleep(0.1)
|
49 | 79 |
|
50 | 80 | def is_done(self):
|
| 81 | + """Check if the total waiting time is bigger or equal to the specified |
| 82 | + maximum waiting time.""" |
51 | 83 | return self.total_wait_time >= self.max_wait_time_sec
|
52 | 84 |
|
53 | 85 |
|
54 | 86 | class RegularPeriodRetry(RetryStrategy):
|
55 |
| - """Check for submissions status periodically for indefinite amount of time.""" |
| 87 | + """Check for submissions status periodically for indefinite amount of time. |
| 88 | +
|
| 89 | + Parameters |
| 90 | + ---------- |
| 91 | + wait_time_sec : float |
| 92 | + Wait time between retries (in seconds). |
| 93 | + """ |
56 | 94 |
|
57 | 95 | def __init__(self, wait_time_sec: float = 0.1):
|
58 | 96 | self.wait_time_sec = wait_time_sec
|
59 | 97 |
|
60 | 98 | def wait(self):
|
| 99 | + """Wait for `wait_time_sec` seconds.""" |
61 | 100 | time.sleep(self.wait_time_sec)
|
62 | 101 |
|
63 | 102 | def is_done(self) -> bool:
|
| 103 | + """Return False, as this retry strategy is indefinite.""" |
64 | 104 | return False
|
| 105 | + |
| 106 | + def step(self) -> None: |
| 107 | + """Satisfy the interface with a dummy implementation.""" |
| 108 | + pass |
0 commit comments