dory-processor-sdk 0.0.1__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.
- dory/__init__.py +101 -0
- dory/auth/__init__.py +10 -0
- dory/auth/oauth2.py +153 -0
- dory/auto_instrument.py +142 -0
- dory/cli/__init__.py +5 -0
- dory/cli/main.py +137 -0
- dory/cli/templates.py +123 -0
- dory/config/__init__.py +23 -0
- dory/config/defaults.py +24 -0
- dory/config/loader.py +430 -0
- dory/config/presets.py +73 -0
- dory/config/schema.py +84 -0
- dory/core/__init__.py +27 -0
- dory/core/app.py +434 -0
- dory/core/context.py +209 -0
- dory/core/lifecycle.py +214 -0
- dory/core/meta.py +121 -0
- dory/core/modes.py +479 -0
- dory/core/processor.py +564 -0
- dory/core/signals.py +122 -0
- dory/decorators.py +142 -0
- dory/edge/__init__.py +88 -0
- dory/edge/adaptive.py +644 -0
- dory/edge/detector.py +546 -0
- dory/edge/fencing.py +488 -0
- dory/edge/heartbeat.py +598 -0
- dory/edge/role.py +419 -0
- dory/errors/__init__.py +139 -0
- dory/errors/classification.py +362 -0
- dory/errors/codes.py +498 -0
- dory/geo/__init__.py +40 -0
- dory/geo/geolocalizer.py +1034 -0
- dory/health/__init__.py +12 -0
- dory/health/probes.py +210 -0
- dory/health/server.py +635 -0
- dory/k8s/__init__.py +80 -0
- dory/k8s/annotation_watcher.py +184 -0
- dory/k8s/client.py +251 -0
- dory/k8s/labels.py +505 -0
- dory/k8s/pod_metadata.py +182 -0
- dory/logging/__init__.py +9 -0
- dory/logging/logger.py +148 -0
- dory/metrics/__init__.py +7 -0
- dory/metrics/collector.py +301 -0
- dory/middleware/__init__.py +46 -0
- dory/middleware/connection_tracker.py +608 -0
- dory/middleware/request_id.py +325 -0
- dory/middleware/request_tracker.py +511 -0
- dory/migration/__init__.py +33 -0
- dory/migration/configmap.py +232 -0
- dory/migration/s3_store.py +594 -0
- dory/migration/serialization.py +135 -0
- dory/migration/state_manager.py +286 -0
- dory/migration/transfer.py +382 -0
- dory/monitoring/__init__.py +29 -0
- dory/monitoring/opentelemetry.py +489 -0
- dory/output/__init__.py +31 -0
- dory/output/envelope.py +137 -0
- dory/output/formatter.py +113 -0
- dory/output/rabbitmq.py +632 -0
- dory/output/routing.py +318 -0
- dory/output/validator.py +199 -0
- dory/py.typed +2 -0
- dory/recovery/__init__.py +60 -0
- dory/recovery/golden_image.py +487 -0
- dory/recovery/golden_snapshot.py +713 -0
- dory/recovery/golden_validator.py +518 -0
- dory/recovery/partial_recovery.py +482 -0
- dory/recovery/recovery_decision.py +242 -0
- dory/recovery/restart_detector.py +142 -0
- dory/recovery/state_validator.py +183 -0
- dory/resilience/__init__.py +45 -0
- dory/resilience/circuit_breaker.py +457 -0
- dory/resilience/retry.py +389 -0
- dory/simple.py +342 -0
- dory/types.py +68 -0
- dory/utils/__init__.py +31 -0
- dory/utils/errors.py +59 -0
- dory/utils/retry.py +115 -0
- dory/utils/timeout.py +80 -0
- dory_processor_sdk-0.0.1.dist-info/METADATA +424 -0
- dory_processor_sdk-0.0.1.dist-info/RECORD +86 -0
- dory_processor_sdk-0.0.1.dist-info/WHEEL +5 -0
- dory_processor_sdk-0.0.1.dist-info/entry_points.txt +2 -0
- dory_processor_sdk-0.0.1.dist-info/licenses/LICENSE +201 -0
- dory_processor_sdk-0.0.1.dist-info/top_level.txt +1 -0
dory/decorators.py
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Decorators for simplified Dory SDK integration.
|
|
3
|
+
|
|
4
|
+
Provides @stateful decorator for automatic state management,
|
|
5
|
+
eliminating the need to manually implement get_state() and restore_state().
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from dataclasses import dataclass, field
|
|
9
|
+
from typing import Any, TypeVar, Generic, Callable
|
|
10
|
+
|
|
11
|
+
T = TypeVar('T')
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass
|
|
15
|
+
class StatefulVar(Generic[T]):
|
|
16
|
+
"""
|
|
17
|
+
A stateful variable that automatically participates in state save/restore.
|
|
18
|
+
|
|
19
|
+
Usage:
|
|
20
|
+
from dory import stateful
|
|
21
|
+
|
|
22
|
+
class MyProcessor(BaseProcessor):
|
|
23
|
+
counter = stateful(0)
|
|
24
|
+
sessions = stateful(dict)
|
|
25
|
+
|
|
26
|
+
async def run(self):
|
|
27
|
+
self.counter += 1 # Automatically saved/restored
|
|
28
|
+
"""
|
|
29
|
+
_default: T | Callable[[], T]
|
|
30
|
+
_name: str = ""
|
|
31
|
+
_value: T = field(default=None, repr=False)
|
|
32
|
+
_initialized: bool = field(default=False, repr=False)
|
|
33
|
+
|
|
34
|
+
def __set_name__(self, owner: type, name: str) -> None:
|
|
35
|
+
"""Called when descriptor is assigned to a class attribute."""
|
|
36
|
+
self._name = name
|
|
37
|
+
# Register this stateful var with the class
|
|
38
|
+
if not hasattr(owner, '_stateful_vars'):
|
|
39
|
+
owner._stateful_vars = {}
|
|
40
|
+
owner._stateful_vars[name] = self
|
|
41
|
+
|
|
42
|
+
def __get__(self, obj: Any, objtype: type | None = None) -> T:
|
|
43
|
+
"""Get the current value."""
|
|
44
|
+
if obj is None:
|
|
45
|
+
return self
|
|
46
|
+
|
|
47
|
+
# Initialize on first access
|
|
48
|
+
if not hasattr(obj, f'_stateful_{self._name}_value'):
|
|
49
|
+
default = self._default() if callable(self._default) else self._default
|
|
50
|
+
setattr(obj, f'_stateful_{self._name}_value', default)
|
|
51
|
+
|
|
52
|
+
return getattr(obj, f'_stateful_{self._name}_value')
|
|
53
|
+
|
|
54
|
+
def __set__(self, obj: Any, value: T) -> None:
|
|
55
|
+
"""Set the value."""
|
|
56
|
+
setattr(obj, f'_stateful_{self._name}_value', value)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def stateful(default: T | Callable[[], T] = None) -> StatefulVar[T]:
|
|
60
|
+
"""
|
|
61
|
+
Mark a class attribute as stateful for automatic state management.
|
|
62
|
+
|
|
63
|
+
The SDK will automatically include this attribute in get_state() output
|
|
64
|
+
and restore it in restore_state().
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
default: Default value or factory function (use factory for mutable defaults)
|
|
68
|
+
|
|
69
|
+
Usage:
|
|
70
|
+
class MyProcessor(BaseProcessor):
|
|
71
|
+
# Simple values
|
|
72
|
+
counter = stateful(0)
|
|
73
|
+
name = stateful("default")
|
|
74
|
+
|
|
75
|
+
# Mutable defaults (use factory to avoid sharing)
|
|
76
|
+
sessions = stateful(dict) # Same as stateful(lambda: {})
|
|
77
|
+
items = stateful(list) # Same as stateful(lambda: [])
|
|
78
|
+
|
|
79
|
+
Example:
|
|
80
|
+
from dory import DoryApp, BaseProcessor, stateful
|
|
81
|
+
|
|
82
|
+
class MyProcessor(BaseProcessor):
|
|
83
|
+
counter = stateful(0)
|
|
84
|
+
data = stateful(dict)
|
|
85
|
+
|
|
86
|
+
async def run(self):
|
|
87
|
+
while not self.context.is_shutdown_requested():
|
|
88
|
+
self.counter += 1
|
|
89
|
+
await asyncio.sleep(1)
|
|
90
|
+
|
|
91
|
+
# No need to implement get_state() or restore_state()!
|
|
92
|
+
# SDK handles it automatically.
|
|
93
|
+
"""
|
|
94
|
+
return StatefulVar(_default=default)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def get_stateful_vars(obj: Any) -> dict[str, Any]:
|
|
98
|
+
"""
|
|
99
|
+
Get all stateful variables from an object.
|
|
100
|
+
|
|
101
|
+
Used internally by SDK to auto-generate get_state().
|
|
102
|
+
"""
|
|
103
|
+
cls = type(obj)
|
|
104
|
+
if not hasattr(cls, '_stateful_vars'):
|
|
105
|
+
return {}
|
|
106
|
+
|
|
107
|
+
result = {}
|
|
108
|
+
for name in cls._stateful_vars:
|
|
109
|
+
result[name] = getattr(obj, name)
|
|
110
|
+
return result
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def set_stateful_vars(obj: Any, state: dict[str, Any]) -> None:
|
|
114
|
+
"""
|
|
115
|
+
Set stateful variables on an object from state dict.
|
|
116
|
+
|
|
117
|
+
Used internally by SDK to auto-generate restore_state().
|
|
118
|
+
"""
|
|
119
|
+
cls = type(obj)
|
|
120
|
+
if not hasattr(cls, '_stateful_vars'):
|
|
121
|
+
return
|
|
122
|
+
|
|
123
|
+
for name in cls._stateful_vars:
|
|
124
|
+
if name in state:
|
|
125
|
+
setattr(obj, name, state[name])
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class StatefulMixin:
|
|
129
|
+
"""
|
|
130
|
+
Mixin that provides automatic get_state() and restore_state() for @stateful vars.
|
|
131
|
+
|
|
132
|
+
If a class has @stateful decorated attributes but doesn't override
|
|
133
|
+
get_state()/restore_state(), this mixin provides default implementations.
|
|
134
|
+
"""
|
|
135
|
+
|
|
136
|
+
def _get_stateful_state(self) -> dict:
|
|
137
|
+
"""Get state from @stateful decorated attributes."""
|
|
138
|
+
return get_stateful_vars(self)
|
|
139
|
+
|
|
140
|
+
def _set_stateful_state(self, state: dict) -> None:
|
|
141
|
+
"""Set state to @stateful decorated attributes."""
|
|
142
|
+
set_stateful_vars(self, state)
|
dory/edge/__init__.py
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"""Edge node support for Dory SDK.
|
|
2
|
+
|
|
3
|
+
Provides fencing, failover coordination, and split-brain prevention
|
|
4
|
+
for edge nodes with intermittent connectivity.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from dory.edge.fencing import (
|
|
8
|
+
FencingManager,
|
|
9
|
+
FencingConfig,
|
|
10
|
+
FencingToken,
|
|
11
|
+
FencingError,
|
|
12
|
+
FenceViolation,
|
|
13
|
+
StaleEpochError,
|
|
14
|
+
)
|
|
15
|
+
from dory.edge.role import (
|
|
16
|
+
ProcessorRole,
|
|
17
|
+
RoleManager,
|
|
18
|
+
RoleTransition,
|
|
19
|
+
)
|
|
20
|
+
from dory.edge.heartbeat import (
|
|
21
|
+
HeartbeatManager,
|
|
22
|
+
HeartbeatConfig,
|
|
23
|
+
HeartbeatPayload,
|
|
24
|
+
HeartbeatResponse,
|
|
25
|
+
ConnectivityStatus,
|
|
26
|
+
ConnectivityMetrics,
|
|
27
|
+
EdgeHealthReporter,
|
|
28
|
+
)
|
|
29
|
+
from dory.edge.detector import (
|
|
30
|
+
WorkloadDetector,
|
|
31
|
+
WorkloadContext,
|
|
32
|
+
NodeType,
|
|
33
|
+
is_edge_node,
|
|
34
|
+
is_cloud_node,
|
|
35
|
+
is_migrated_workload,
|
|
36
|
+
get_workload_context,
|
|
37
|
+
get_node_type,
|
|
38
|
+
get_recommended_env_vars,
|
|
39
|
+
get_pod_spec_yaml_snippet,
|
|
40
|
+
)
|
|
41
|
+
from dory.edge.adaptive import (
|
|
42
|
+
AdaptiveProcessor,
|
|
43
|
+
AdaptiveConfig,
|
|
44
|
+
EdgeConfig,
|
|
45
|
+
OperationMode,
|
|
46
|
+
create_adaptive_processor,
|
|
47
|
+
get_location_aware_settings,
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
__all__ = [
|
|
51
|
+
# Fencing
|
|
52
|
+
"FencingManager",
|
|
53
|
+
"FencingConfig",
|
|
54
|
+
"FencingToken",
|
|
55
|
+
"FencingError",
|
|
56
|
+
"FenceViolation",
|
|
57
|
+
"StaleEpochError",
|
|
58
|
+
# Role management
|
|
59
|
+
"ProcessorRole",
|
|
60
|
+
"RoleManager",
|
|
61
|
+
"RoleTransition",
|
|
62
|
+
# Heartbeat and connectivity
|
|
63
|
+
"HeartbeatManager",
|
|
64
|
+
"HeartbeatConfig",
|
|
65
|
+
"HeartbeatPayload",
|
|
66
|
+
"HeartbeatResponse",
|
|
67
|
+
"ConnectivityStatus",
|
|
68
|
+
"ConnectivityMetrics",
|
|
69
|
+
"EdgeHealthReporter",
|
|
70
|
+
# Workload detection
|
|
71
|
+
"WorkloadDetector",
|
|
72
|
+
"WorkloadContext",
|
|
73
|
+
"NodeType",
|
|
74
|
+
"is_edge_node",
|
|
75
|
+
"is_cloud_node",
|
|
76
|
+
"is_migrated_workload",
|
|
77
|
+
"get_workload_context",
|
|
78
|
+
"get_node_type",
|
|
79
|
+
"get_recommended_env_vars",
|
|
80
|
+
"get_pod_spec_yaml_snippet",
|
|
81
|
+
# Adaptive processor
|
|
82
|
+
"AdaptiveProcessor",
|
|
83
|
+
"AdaptiveConfig",
|
|
84
|
+
"EdgeConfig",
|
|
85
|
+
"OperationMode",
|
|
86
|
+
"create_adaptive_processor",
|
|
87
|
+
"get_location_aware_settings",
|
|
88
|
+
]
|