|
24 | 24 |
|
25 | 25 | import time |
26 | 26 | from dataclasses import dataclass |
27 | | -from typing import Dict, List, Optional, TypedDict |
| 27 | +from typing import Dict, List, Optional |
28 | 28 | from urllib.parse import urlparse |
29 | 29 |
|
30 | 30 | import aiohttp |
31 | 31 |
|
32 | | -_DEFAULT_MAX_ATTEMPTS = 3 |
33 | | -_DEFAULT_BACKOFF_BASE = 0.2 |
| 32 | +FAILOVER_MAX_ATTEMPTS = 3 |
| 33 | +FAILOVER_BACKOFF_BASE = 0.2 # seconds |
34 | 34 |
|
35 | 35 |
|
36 | | -class FailoverOptions(TypedDict, total=False): |
37 | | - """Region-failover tuning, passed as the ``failover`` argument. Use it as a |
38 | | - plain dict, e.g. ``failover={"max_attempts": 5}``. All keys are optional. |
39 | | -
|
40 | | - Keys: |
41 | | - max_attempts: total number of attempts including the initial request — |
42 | | - the original host plus up to ``max_attempts - 1`` fallback regions. |
43 | | - Defaults to 3. Set to 1 to disable failover (a single attempt). |
44 | | - backoff_base: seconds before the first retry; each subsequent retry |
45 | | - doubles it. Defaults to 0.2. |
46 | | - """ |
47 | | - |
48 | | - max_attempts: int |
49 | | - backoff_base: float |
50 | | - |
51 | | - |
52 | | -def failover_attempts(failover: Optional[FailoverOptions], host: Optional[str]) -> int: |
53 | | - """Total request attempts including the initial one; 1 means no failover. |
54 | | -
|
55 | | - With no config (``None``) failover is enabled only for LiveKit Cloud hosts. |
56 | | - An explicit config enables it for any host; ``max_attempts=1`` disables it. |
| 36 | +def failover_attempts(enabled: bool, host: Optional[str], force: bool = False) -> int: |
| 37 | + """Total request attempts for a host; 1 means no failover. Failover only |
| 38 | + engages when enabled and the host is a LiveKit Cloud domain. ``force`` |
| 39 | + bypasses the cloud-host check and is for internal testing only. |
57 | 40 | """ |
58 | | - if failover is None: |
59 | | - return _DEFAULT_MAX_ATTEMPTS if (bool(host) and is_cloud(host)) else 1 # type: ignore[arg-type] |
60 | | - return max(1, failover.get("max_attempts", _DEFAULT_MAX_ATTEMPTS)) |
61 | | - |
62 | | - |
63 | | -def failover_backoff_base(failover: Optional[FailoverOptions]) -> float: |
64 | | - return (failover or {}).get("backoff_base", _DEFAULT_BACKOFF_BASE) |
| 41 | + if enabled and (force or (bool(host) and is_cloud(host))): |
| 42 | + return FAILOVER_MAX_ATTEMPTS |
| 43 | + return 1 |
65 | 44 |
|
66 | 45 |
|
67 | 46 | def is_cloud(host: str) -> bool: |
68 | | - # Auto mode only enables failover for LiveKit Cloud project domains. |
| 47 | + # Failover only engages for LiveKit Cloud project domains. |
69 | 48 | return host.endswith(".livekit.cloud") |
70 | 49 |
|
71 | 50 |
|
|
0 commit comments