-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy paththrottling_and_retry.py
More file actions
70 lines (50 loc) · 1.79 KB
/
Copy paththrottling_and_retry.py
File metadata and controls
70 lines (50 loc) · 1.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
"""Throttling and retry with offwork.
Demonstrates:
- @offwork.task(throttle=timedelta) — rate-limit executions
- @offwork.task(retries=N, retry_delay=T) — retry with exponential backoff
- Combining throttle + retry
Usage:
# Terminal 1 -- start a worker
offwork worker --backend local://localhost:9748 --tmp
# Terminal 2 -- run this script
offwork run examples/throttling_and_retry.py
"""
import asyncio
import random
from datetime import timedelta
import offwork
from offwork import ThrottleError
offwork.connect("local://localhost:9748")
# --- Throttling: at most once every 5 seconds ---
@offwork.task(throttle=timedelta(seconds=5))
def expensive_query(query: str) -> str:
return f"Result for '{query}'"
# --- Retry: 3 attempts with exponential backoff ---
@offwork.task(retries=3, retry_delay=0.5)
def flaky_operation(x: int) -> int:
if random.random() < 0.5:
raise RuntimeError("Random failure!")
return x * 2
async def main() -> None:
# 1. Throttling demo
print("— Throttle demo (5s cooldown) —")
result = await expensive_query.run("first call")
print(f" Call 1: {result}")
try:
result = await expensive_query.run("second call (too soon)")
print(f" Call 2: {result}")
except ThrottleError:
print(" Call 2: ThrottleError — rate limited!")
# Wait for cooldown
print(" Waiting 5s for cooldown...")
await asyncio.sleep(5)
result = await expensive_query.run("third call (after cooldown)")
print(f" Call 3: {result}")
# 2. Retry demo
print("\n— Retry demo (3 retries, 0.5s base delay) —")
try:
result = await flaky_operation.run(21)
print(f" Result: {result}")
except Exception as exc:
print(f" Failed after retries: {exc}")
asyncio.run(main())