File size: 2,207 Bytes
bdc2878
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
"""Per-operation timeout / retry profiles for the reverse pipeline.

Pre-built profiles eliminate per-request config lookups in the hot path.
Each profile specifies timeout, max retries, and retry-eligible status codes.
"""

from dataclasses import dataclass, field


@dataclass(slots=True, frozen=True)
class OperationProfile:
    """Timeout and retry configuration for one operation type."""
    timeout_s:       float        = 30.0
    max_retries:     int          = 0
    retry_codes:     frozenset[int] = frozenset()
    retry_delay_s:   float        = 1.0
    idle_timeout_s:  float        = 0.0   # 0 = no idle timeout


# ---------------------------------------------------------------------------
# Pre-built profiles
# ---------------------------------------------------------------------------

CHAT = OperationProfile(
    timeout_s      = 120.0,
    max_retries    = 1,
    retry_codes    = frozenset({502, 503}),
    retry_delay_s  = 2.0,
    idle_timeout_s = 30.0,
)

IMAGE = OperationProfile(
    timeout_s      = 300.0,
    max_retries    = 0,
    idle_timeout_s = 60.0,
)

IMAGE_EDIT = OperationProfile(
    timeout_s      = 120.0,
    max_retries    = 1,
    retry_codes    = frozenset({502, 503}),
    retry_delay_s  = 2.0,
    idle_timeout_s = 30.0,
)

VIDEO = OperationProfile(
    timeout_s      = 60.0,
    max_retries    = 1,
    retry_codes    = frozenset({502, 503, 429}),
    retry_delay_s  = 5.0,
)

VOICE = OperationProfile(
    timeout_s      = 120.0,
    max_retries    = 0,
    idle_timeout_s = 15.0,
)

ASSET = OperationProfile(
    timeout_s      = 60.0,
    max_retries    = 2,
    retry_codes    = frozenset({502, 503}),
    retry_delay_s  = 1.0,
)

GRPC = OperationProfile(
    timeout_s      = 15.0,
    max_retries    = 1,
    retry_codes    = frozenset({503}),
    retry_delay_s  = 0.5,
)

# Lookup by name for programmatic access.
PROFILES: dict[str, OperationProfile] = {
    "chat":       CHAT,
    "image":      IMAGE,
    "image_edit": IMAGE_EDIT,
    "video":      VIDEO,
    "voice":      VOICE,
    "asset":      ASSET,
    "grpc":       GRPC,
}


__all__ = ["OperationProfile", "PROFILES", "CHAT", "IMAGE", "IMAGE_EDIT", "VIDEO", "VOICE", "ASSET", "GRPC"]