puffinflow 2.dev0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- puffinflow/__init__.py +132 -0
- puffinflow/core/__init__.py +110 -0
- puffinflow/core/agent/__init__.py +320 -0
- puffinflow/core/agent/base.py +1635 -0
- puffinflow/core/agent/checkpoint.py +50 -0
- puffinflow/core/agent/context.py +521 -0
- puffinflow/core/agent/decorators/__init__.py +90 -0
- puffinflow/core/agent/decorators/builder.py +454 -0
- puffinflow/core/agent/decorators/flexible.py +714 -0
- puffinflow/core/agent/decorators/inspection.py +144 -0
- puffinflow/core/agent/dependencies.py +57 -0
- puffinflow/core/agent/scheduling/__init__.py +21 -0
- puffinflow/core/agent/scheduling/builder.py +160 -0
- puffinflow/core/agent/scheduling/exceptions.py +35 -0
- puffinflow/core/agent/scheduling/inputs.py +137 -0
- puffinflow/core/agent/scheduling/parser.py +209 -0
- puffinflow/core/agent/scheduling/scheduler.py +413 -0
- puffinflow/core/agent/state.py +141 -0
- puffinflow/core/config.py +62 -0
- puffinflow/core/coordination/__init__.py +137 -0
- puffinflow/core/coordination/agent_group.py +359 -0
- puffinflow/core/coordination/agent_pool.py +629 -0
- puffinflow/core/coordination/agent_team.py +577 -0
- puffinflow/core/coordination/coordinator.py +720 -0
- puffinflow/core/coordination/deadlock.py +1759 -0
- puffinflow/core/coordination/fluent_api.py +421 -0
- puffinflow/core/coordination/primitives.py +478 -0
- puffinflow/core/coordination/rate_limiter.py +520 -0
- puffinflow/core/observability/__init__.py +47 -0
- puffinflow/core/observability/agent.py +139 -0
- puffinflow/core/observability/alerting.py +73 -0
- puffinflow/core/observability/config.py +127 -0
- puffinflow/core/observability/context.py +88 -0
- puffinflow/core/observability/core.py +147 -0
- puffinflow/core/observability/decorators.py +105 -0
- puffinflow/core/observability/events.py +71 -0
- puffinflow/core/observability/interfaces.py +196 -0
- puffinflow/core/observability/metrics.py +137 -0
- puffinflow/core/observability/tracing.py +209 -0
- puffinflow/core/reliability/__init__.py +27 -0
- puffinflow/core/reliability/bulkhead.py +96 -0
- puffinflow/core/reliability/circuit_breaker.py +149 -0
- puffinflow/core/reliability/leak_detector.py +122 -0
- puffinflow/core/resources/__init__.py +77 -0
- puffinflow/core/resources/allocation.py +790 -0
- puffinflow/core/resources/pool.py +645 -0
- puffinflow/core/resources/quotas.py +567 -0
- puffinflow/core/resources/requirements.py +217 -0
- puffinflow/version.py +21 -0
- puffinflow-2.dev0.dist-info/METADATA +334 -0
- puffinflow-2.dev0.dist-info/RECORD +55 -0
- puffinflow-2.dev0.dist-info/WHEEL +5 -0
- puffinflow-2.dev0.dist-info/entry_points.txt +3 -0
- puffinflow-2.dev0.dist-info/licenses/LICENSE +21 -0
- puffinflow-2.dev0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Builder pattern for constructing state configurations.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Any, Callable, Optional, Union
|
|
6
|
+
|
|
7
|
+
from ..state import Priority
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class StateBuilder:
|
|
11
|
+
"""Builder pattern for constructing state configurations."""
|
|
12
|
+
|
|
13
|
+
def __init__(self) -> None:
|
|
14
|
+
self._config: dict[str, Any] = {}
|
|
15
|
+
|
|
16
|
+
# Resource methods
|
|
17
|
+
def cpu(self, units: float) -> "StateBuilder":
|
|
18
|
+
"""Set CPU units."""
|
|
19
|
+
self._config["cpu"] = units
|
|
20
|
+
return self
|
|
21
|
+
|
|
22
|
+
def memory(self, mb: float) -> "StateBuilder":
|
|
23
|
+
"""Set memory in MB."""
|
|
24
|
+
self._config["memory"] = mb
|
|
25
|
+
return self
|
|
26
|
+
|
|
27
|
+
def gpu(self, units: float) -> "StateBuilder":
|
|
28
|
+
"""Set GPU units."""
|
|
29
|
+
self._config["gpu"] = units
|
|
30
|
+
return self
|
|
31
|
+
|
|
32
|
+
def io(self, weight: float) -> "StateBuilder":
|
|
33
|
+
"""Set I/O weight."""
|
|
34
|
+
self._config["io"] = weight
|
|
35
|
+
return self
|
|
36
|
+
|
|
37
|
+
def network(self, weight: float) -> "StateBuilder":
|
|
38
|
+
"""Set network weight."""
|
|
39
|
+
self._config["network"] = weight
|
|
40
|
+
return self
|
|
41
|
+
|
|
42
|
+
def resources(
|
|
43
|
+
self,
|
|
44
|
+
cpu: Optional[float] = None,
|
|
45
|
+
memory: Optional[float] = None,
|
|
46
|
+
gpu: Optional[float] = None,
|
|
47
|
+
io: Optional[float] = None,
|
|
48
|
+
network: Optional[float] = None,
|
|
49
|
+
) -> "StateBuilder":
|
|
50
|
+
"""Set multiple resources at once."""
|
|
51
|
+
if cpu is not None:
|
|
52
|
+
self._config["cpu"] = cpu
|
|
53
|
+
if memory is not None:
|
|
54
|
+
self._config["memory"] = memory
|
|
55
|
+
if gpu is not None:
|
|
56
|
+
self._config["gpu"] = gpu
|
|
57
|
+
if io is not None:
|
|
58
|
+
self._config["io"] = io
|
|
59
|
+
if network is not None:
|
|
60
|
+
self._config["network"] = network
|
|
61
|
+
return self
|
|
62
|
+
|
|
63
|
+
# Priority and timing
|
|
64
|
+
def priority(self, level: Union[Priority, int, str]) -> "StateBuilder":
|
|
65
|
+
"""Set priority level."""
|
|
66
|
+
self._config["priority"] = level
|
|
67
|
+
return self
|
|
68
|
+
|
|
69
|
+
def high_priority(self) -> "StateBuilder":
|
|
70
|
+
"""Set high priority."""
|
|
71
|
+
self._config["priority"] = Priority.HIGH
|
|
72
|
+
return self
|
|
73
|
+
|
|
74
|
+
def critical_priority(self) -> "StateBuilder":
|
|
75
|
+
"""Set critical priority."""
|
|
76
|
+
self._config["priority"] = Priority.CRITICAL
|
|
77
|
+
return self
|
|
78
|
+
|
|
79
|
+
def low_priority(self) -> "StateBuilder":
|
|
80
|
+
"""Set low priority."""
|
|
81
|
+
self._config["priority"] = Priority.LOW
|
|
82
|
+
return self
|
|
83
|
+
|
|
84
|
+
def timeout(self, seconds: float) -> "StateBuilder":
|
|
85
|
+
"""Set execution timeout."""
|
|
86
|
+
self._config["timeout"] = seconds
|
|
87
|
+
return self
|
|
88
|
+
|
|
89
|
+
# Rate limiting
|
|
90
|
+
def rate_limit(self, rate: float, burst: Optional[int] = None) -> "StateBuilder":
|
|
91
|
+
"""Set rate limiting."""
|
|
92
|
+
self._config["rate_limit"] = rate
|
|
93
|
+
if burst:
|
|
94
|
+
self._config["burst_limit"] = burst
|
|
95
|
+
return self
|
|
96
|
+
|
|
97
|
+
def throttle(self, rate: float) -> "StateBuilder":
|
|
98
|
+
"""Alias for rate_limit."""
|
|
99
|
+
return self.rate_limit(rate)
|
|
100
|
+
|
|
101
|
+
# Coordination
|
|
102
|
+
def mutex(self) -> "StateBuilder":
|
|
103
|
+
"""Enable mutual exclusion."""
|
|
104
|
+
self._config["mutex"] = True
|
|
105
|
+
return self
|
|
106
|
+
|
|
107
|
+
def exclusive(self) -> "StateBuilder":
|
|
108
|
+
"""Alias for mutex."""
|
|
109
|
+
return self.mutex()
|
|
110
|
+
|
|
111
|
+
def semaphore(self, count: int) -> "StateBuilder":
|
|
112
|
+
"""Enable semaphore with count."""
|
|
113
|
+
self._config["semaphore"] = count
|
|
114
|
+
return self
|
|
115
|
+
|
|
116
|
+
def concurrent(self, max_concurrent: int) -> "StateBuilder":
|
|
117
|
+
"""Alias for semaphore."""
|
|
118
|
+
return self.semaphore(max_concurrent)
|
|
119
|
+
|
|
120
|
+
def barrier(self, parties: int) -> "StateBuilder":
|
|
121
|
+
"""Enable barrier synchronization."""
|
|
122
|
+
self._config["barrier"] = parties
|
|
123
|
+
return self
|
|
124
|
+
|
|
125
|
+
def synchronized(self, parties: int) -> "StateBuilder":
|
|
126
|
+
"""Alias for barrier."""
|
|
127
|
+
return self.barrier(parties)
|
|
128
|
+
|
|
129
|
+
def lease(self, duration: float) -> "StateBuilder":
|
|
130
|
+
"""Enable time-based lease."""
|
|
131
|
+
self._config["lease"] = duration
|
|
132
|
+
return self
|
|
133
|
+
|
|
134
|
+
def quota(self, limit: float) -> "StateBuilder":
|
|
135
|
+
"""Enable quota management."""
|
|
136
|
+
self._config["quota"] = limit
|
|
137
|
+
return self
|
|
138
|
+
|
|
139
|
+
# Dependencies
|
|
140
|
+
def depends_on(self, *states: str) -> "StateBuilder":
|
|
141
|
+
"""Set state dependencies."""
|
|
142
|
+
self._config["depends_on"] = list(states)
|
|
143
|
+
return self
|
|
144
|
+
|
|
145
|
+
def after(self, *states: str) -> "StateBuilder":
|
|
146
|
+
"""Alias for depends_on."""
|
|
147
|
+
return self.depends_on(*states)
|
|
148
|
+
|
|
149
|
+
# Retry configuration
|
|
150
|
+
def retry(
|
|
151
|
+
self,
|
|
152
|
+
max_retries: int,
|
|
153
|
+
initial_delay: float = 1.0,
|
|
154
|
+
exponential_base: float = 2.0,
|
|
155
|
+
jitter: bool = True,
|
|
156
|
+
dead_letter: bool = True,
|
|
157
|
+
circuit_breaker: bool = False,
|
|
158
|
+
) -> "StateBuilder":
|
|
159
|
+
"""Set retry configuration with dead letter options and circuit breaker integration"""
|
|
160
|
+
self._config["retry_config"] = {
|
|
161
|
+
"max_retries": max_retries,
|
|
162
|
+
"initial_delay": initial_delay,
|
|
163
|
+
"exponential_base": exponential_base,
|
|
164
|
+
"jitter": jitter,
|
|
165
|
+
"dead_letter_on_max_retries": dead_letter,
|
|
166
|
+
"dead_letter_on_timeout": dead_letter,
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
# Enable circuit breaker if requested for retry scenarios
|
|
170
|
+
if circuit_breaker:
|
|
171
|
+
self._config["circuit_breaker"] = True
|
|
172
|
+
|
|
173
|
+
return self
|
|
174
|
+
|
|
175
|
+
def retries(self, count: int) -> "StateBuilder":
|
|
176
|
+
"""Set simple retry count."""
|
|
177
|
+
self._config["max_retries"] = count
|
|
178
|
+
return self
|
|
179
|
+
|
|
180
|
+
def no_retry(self) -> "StateBuilder":
|
|
181
|
+
"""Disable retries."""
|
|
182
|
+
self._config["max_retries"] = 0
|
|
183
|
+
return self
|
|
184
|
+
|
|
185
|
+
# Dead letter configuration
|
|
186
|
+
def enable_dead_letter(self) -> "StateBuilder":
|
|
187
|
+
"""Enable dead letter queue on failure"""
|
|
188
|
+
self._config["dead_letter"] = True
|
|
189
|
+
return self
|
|
190
|
+
|
|
191
|
+
def disable_dead_letter(self) -> "StateBuilder":
|
|
192
|
+
"""Disable dead letter queue - fail permanently instead"""
|
|
193
|
+
self._config["no_dead_letter"] = True
|
|
194
|
+
return self
|
|
195
|
+
|
|
196
|
+
def no_dlq(self) -> "StateBuilder":
|
|
197
|
+
"""Alias for disable_dead_letter"""
|
|
198
|
+
return self.disable_dead_letter()
|
|
199
|
+
|
|
200
|
+
def with_dead_letter(self, enabled: bool = True) -> "StateBuilder":
|
|
201
|
+
"""Configure dead letter behavior"""
|
|
202
|
+
self._config["dead_letter"] = enabled
|
|
203
|
+
return self
|
|
204
|
+
|
|
205
|
+
# NEW: Circuit Breaker methods
|
|
206
|
+
def circuit_breaker(
|
|
207
|
+
self,
|
|
208
|
+
enabled: bool = True,
|
|
209
|
+
failure_threshold: int = 5,
|
|
210
|
+
recovery_timeout: float = 60.0,
|
|
211
|
+
success_threshold: int = 3,
|
|
212
|
+
) -> "StateBuilder":
|
|
213
|
+
"""Enable circuit breaker with configuration"""
|
|
214
|
+
self._config["circuit_breaker"] = enabled
|
|
215
|
+
if enabled:
|
|
216
|
+
self._config["circuit_breaker_config"] = {
|
|
217
|
+
"failure_threshold": failure_threshold,
|
|
218
|
+
"recovery_timeout": recovery_timeout,
|
|
219
|
+
"success_threshold": success_threshold,
|
|
220
|
+
}
|
|
221
|
+
return self
|
|
222
|
+
|
|
223
|
+
def with_circuit_breaker(self, **config: Any) -> "StateBuilder":
|
|
224
|
+
"""Enable circuit breaker with custom configuration"""
|
|
225
|
+
self._config["circuit_breaker"] = True
|
|
226
|
+
self._config["circuit_breaker_config"] = config
|
|
227
|
+
return self
|
|
228
|
+
|
|
229
|
+
def protected(
|
|
230
|
+
self, failure_threshold: int = 3, recovery_timeout: float = 30.0
|
|
231
|
+
) -> "StateBuilder":
|
|
232
|
+
"""Enable circuit breaker with sensible defaults for protection"""
|
|
233
|
+
return self.circuit_breaker(True, failure_threshold, recovery_timeout)
|
|
234
|
+
|
|
235
|
+
def fragile(
|
|
236
|
+
self, failure_threshold: int = 2, recovery_timeout: float = 120.0
|
|
237
|
+
) -> "StateBuilder":
|
|
238
|
+
"""Enable circuit breaker for fragile operations (low threshold, long recovery)"""
|
|
239
|
+
return self.circuit_breaker(True, failure_threshold, recovery_timeout)
|
|
240
|
+
|
|
241
|
+
# NEW: Bulkhead methods
|
|
242
|
+
def bulkhead(
|
|
243
|
+
self,
|
|
244
|
+
enabled: bool = True,
|
|
245
|
+
max_concurrent: int = 5,
|
|
246
|
+
max_queue_size: int = 100,
|
|
247
|
+
timeout: float = 30.0,
|
|
248
|
+
) -> "StateBuilder":
|
|
249
|
+
"""Enable bulkhead with configuration"""
|
|
250
|
+
self._config["bulkhead"] = enabled
|
|
251
|
+
if enabled:
|
|
252
|
+
self._config["bulkhead_config"] = {
|
|
253
|
+
"max_concurrent": max_concurrent,
|
|
254
|
+
"max_queue_size": max_queue_size,
|
|
255
|
+
"timeout": timeout,
|
|
256
|
+
}
|
|
257
|
+
return self
|
|
258
|
+
|
|
259
|
+
def with_bulkhead(self, **config: Any) -> "StateBuilder":
|
|
260
|
+
"""Enable bulkhead with custom configuration"""
|
|
261
|
+
self._config["bulkhead"] = True
|
|
262
|
+
self._config["bulkhead_config"] = config
|
|
263
|
+
return self
|
|
264
|
+
|
|
265
|
+
def isolated(self, max_concurrent: int = 3) -> "StateBuilder":
|
|
266
|
+
"""Enable bulkhead with isolation (limited concurrency)"""
|
|
267
|
+
return self.bulkhead(True, max_concurrent)
|
|
268
|
+
|
|
269
|
+
def single_threaded(self) -> "StateBuilder":
|
|
270
|
+
"""Enable bulkhead with single thread execution"""
|
|
271
|
+
return self.bulkhead(True, max_concurrent=1)
|
|
272
|
+
|
|
273
|
+
def highly_concurrent(self, max_concurrent: int = 20) -> "StateBuilder":
|
|
274
|
+
"""Enable bulkhead allowing high concurrency"""
|
|
275
|
+
return self.bulkhead(True, max_concurrent)
|
|
276
|
+
|
|
277
|
+
# NEW: Leak Detection methods
|
|
278
|
+
def leak_detection(self, enabled: bool = True) -> "StateBuilder":
|
|
279
|
+
"""Configure resource leak detection"""
|
|
280
|
+
self._config["leak_detection"] = enabled
|
|
281
|
+
return self
|
|
282
|
+
|
|
283
|
+
def no_leak_detection(self) -> "StateBuilder":
|
|
284
|
+
"""Disable resource leak detection"""
|
|
285
|
+
self._config["leak_detection"] = False
|
|
286
|
+
return self
|
|
287
|
+
|
|
288
|
+
# NEW: Combined reliability methods
|
|
289
|
+
def fault_tolerant(
|
|
290
|
+
self,
|
|
291
|
+
circuit_breaker: bool = True,
|
|
292
|
+
bulkhead: bool = True,
|
|
293
|
+
max_concurrent: int = 3,
|
|
294
|
+
failure_threshold: int = 3,
|
|
295
|
+
) -> "StateBuilder":
|
|
296
|
+
"""Enable comprehensive fault tolerance"""
|
|
297
|
+
if circuit_breaker:
|
|
298
|
+
self.circuit_breaker(True, failure_threshold)
|
|
299
|
+
if bulkhead:
|
|
300
|
+
self.bulkhead(True, max_concurrent)
|
|
301
|
+
return self.retry(5, dead_letter=True, circuit_breaker=circuit_breaker)
|
|
302
|
+
|
|
303
|
+
def production_ready(self) -> "StateBuilder":
|
|
304
|
+
"""Apply production-ready reliability patterns"""
|
|
305
|
+
return (
|
|
306
|
+
self.circuit_breaker(True, failure_threshold=5, recovery_timeout=60.0)
|
|
307
|
+
.bulkhead(True, max_concurrent=5)
|
|
308
|
+
.retry(3, dead_letter=True)
|
|
309
|
+
.leak_detection(True)
|
|
310
|
+
)
|
|
311
|
+
|
|
312
|
+
def external_call(self, timeout: float = 30.0) -> "StateBuilder":
|
|
313
|
+
"""Configure for external service calls"""
|
|
314
|
+
return (
|
|
315
|
+
self.circuit_breaker(True, failure_threshold=2, recovery_timeout=30.0)
|
|
316
|
+
.bulkhead(True, max_concurrent=10)
|
|
317
|
+
.timeout(timeout)
|
|
318
|
+
.retry(3, dead_letter=True)
|
|
319
|
+
)
|
|
320
|
+
|
|
321
|
+
# Metadata
|
|
322
|
+
def tag(self, key: str, value: Any) -> "StateBuilder":
|
|
323
|
+
"""Add a tag."""
|
|
324
|
+
if "tags" not in self._config:
|
|
325
|
+
self._config["tags"] = {}
|
|
326
|
+
self._config["tags"][key] = value
|
|
327
|
+
return self
|
|
328
|
+
|
|
329
|
+
def tags(self, **tags: Any) -> "StateBuilder":
|
|
330
|
+
"""Add multiple tags."""
|
|
331
|
+
if "tags" not in self._config:
|
|
332
|
+
self._config["tags"] = {}
|
|
333
|
+
self._config["tags"].update(tags)
|
|
334
|
+
return self
|
|
335
|
+
|
|
336
|
+
def description(self, desc: str) -> "StateBuilder":
|
|
337
|
+
"""Set description."""
|
|
338
|
+
self._config["description"] = desc
|
|
339
|
+
return self
|
|
340
|
+
|
|
341
|
+
def describe(self, desc: str) -> "StateBuilder":
|
|
342
|
+
"""Alias for description."""
|
|
343
|
+
return self.description(desc)
|
|
344
|
+
|
|
345
|
+
# Profile application
|
|
346
|
+
def profile(self, name: str) -> "StateBuilder":
|
|
347
|
+
"""Apply a profile."""
|
|
348
|
+
self._config["profile"] = name
|
|
349
|
+
return self
|
|
350
|
+
|
|
351
|
+
def like(self, name: str) -> "StateBuilder":
|
|
352
|
+
"""Alias for profile."""
|
|
353
|
+
return self.profile(name)
|
|
354
|
+
|
|
355
|
+
# Advanced options
|
|
356
|
+
def preemptible(self, value: bool = True) -> "StateBuilder":
|
|
357
|
+
"""Set preemptible flag."""
|
|
358
|
+
self._config["preemptible"] = value
|
|
359
|
+
return self
|
|
360
|
+
|
|
361
|
+
def checkpoint_every(self, seconds: float) -> "StateBuilder":
|
|
362
|
+
"""Set checkpoint interval."""
|
|
363
|
+
self._config["checkpoint_interval"] = seconds
|
|
364
|
+
return self
|
|
365
|
+
|
|
366
|
+
def cleanup_on_failure(self, value: bool = True) -> "StateBuilder":
|
|
367
|
+
"""Set cleanup on failure flag."""
|
|
368
|
+
self._config["cleanup_on_failure"] = value
|
|
369
|
+
return self
|
|
370
|
+
|
|
371
|
+
# Build methods
|
|
372
|
+
def build(self) -> dict[str, Any]:
|
|
373
|
+
"""Build and return the configuration dictionary."""
|
|
374
|
+
return self._config.copy()
|
|
375
|
+
|
|
376
|
+
def __call__(self, func: Callable[..., Any]) -> Callable[..., Any]:
|
|
377
|
+
"""Use as decorator."""
|
|
378
|
+
from .flexible import state
|
|
379
|
+
|
|
380
|
+
decorator = state(config=self._config)
|
|
381
|
+
return decorator(func) # type: ignore[no-any-return]
|
|
382
|
+
|
|
383
|
+
def decorator(self) -> Callable[..., Any]:
|
|
384
|
+
"""Get decorator function."""
|
|
385
|
+
from .flexible import state
|
|
386
|
+
|
|
387
|
+
return state(config=self._config)
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
def build_state() -> StateBuilder:
|
|
391
|
+
"""Create a new state builder."""
|
|
392
|
+
return StateBuilder()
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
# Convenience builder functions
|
|
396
|
+
def cpu_state(units: float) -> StateBuilder:
|
|
397
|
+
"""Start building a CPU-intensive state."""
|
|
398
|
+
return StateBuilder().cpu(units)
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
def memory_state(mb: float) -> StateBuilder:
|
|
402
|
+
"""Start building a memory-intensive state."""
|
|
403
|
+
return StateBuilder().memory(mb)
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
def gpu_state(units: float) -> StateBuilder:
|
|
407
|
+
"""Start building a GPU state."""
|
|
408
|
+
return StateBuilder().gpu(units)
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
def exclusive_state() -> StateBuilder:
|
|
412
|
+
"""Start building an exclusive state."""
|
|
413
|
+
return StateBuilder().mutex()
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
def concurrent_state(max_concurrent: int) -> StateBuilder:
|
|
417
|
+
"""Start building a concurrent state."""
|
|
418
|
+
return StateBuilder().semaphore(max_concurrent)
|
|
419
|
+
|
|
420
|
+
|
|
421
|
+
def high_priority_state() -> StateBuilder:
|
|
422
|
+
"""Start building a high priority state."""
|
|
423
|
+
return StateBuilder().high_priority()
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
def critical_state() -> StateBuilder:
|
|
427
|
+
"""Start building a critical state."""
|
|
428
|
+
return StateBuilder().critical_priority()
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
# NEW: Reliability-focused builders
|
|
432
|
+
def fault_tolerant_state() -> StateBuilder:
|
|
433
|
+
"""Start building a fault-tolerant state."""
|
|
434
|
+
return StateBuilder().fault_tolerant()
|
|
435
|
+
|
|
436
|
+
|
|
437
|
+
def external_service_state(timeout: float = 30.0) -> StateBuilder:
|
|
438
|
+
"""Start building a state for external service calls."""
|
|
439
|
+
return StateBuilder().external_call(timeout)
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
def production_state() -> StateBuilder:
|
|
443
|
+
"""Start building a production-ready state."""
|
|
444
|
+
return StateBuilder().production_ready()
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
def protected_state(failure_threshold: int = 3) -> StateBuilder:
|
|
448
|
+
"""Start building a circuit breaker protected state."""
|
|
449
|
+
return StateBuilder().protected(failure_threshold)
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
def isolated_state(max_concurrent: int = 3) -> StateBuilder:
|
|
453
|
+
"""Start building an isolated (bulkhead) state."""
|
|
454
|
+
return StateBuilder().isolated(max_concurrent)
|