wool 0.1rc20__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.
@@ -0,0 +1,249 @@
1
+ from __future__ import annotations
2
+
3
+ import uuid
4
+ from abc import ABC
5
+ from abc import abstractmethod
6
+ from dataclasses import dataclass
7
+ from dataclasses import field
8
+ from types import MappingProxyType
9
+ from typing import AsyncIterator
10
+ from typing import Callable
11
+ from typing import Final
12
+ from typing import Literal
13
+ from typing import Protocol
14
+ from typing import TypeAlias
15
+ from typing import TypeVar
16
+ from typing import runtime_checkable
17
+
18
+ from wool.core.protobuf.worker import WorkerInfo as WorkerInfoProtobuf
19
+
20
+ T: Final = TypeVar("T")
21
+
22
+ # public
23
+ PredicateFunction: TypeAlias = Callable[[T], bool]
24
+
25
+
26
+ # public
27
+ @dataclass(frozen=True)
28
+ class WorkerInfo:
29
+ """Properties and metadata for a worker instance.
30
+
31
+ Contains identifying information and capabilities of a worker that
32
+ can be used for discovery, filtering, and routing decisions.
33
+
34
+ :param uid:
35
+ Unique identifier for the worker instance (UUID).
36
+ :param host:
37
+ Network host address where the worker is accessible.
38
+ :param port:
39
+ Network port number where the worker is listening.
40
+ :param pid:
41
+ Process ID of the worker.
42
+ :param version:
43
+ Version string of the worker software.
44
+ :param tags:
45
+ Frozenset of capability tags for worker filtering and selection.
46
+ :param extra:
47
+ Additional arbitrary metadata as immutable key-value pairs.
48
+ """
49
+
50
+ uid: uuid.UUID
51
+ host: str = field(hash=False)
52
+ port: int | None = field(hash=False)
53
+ pid: int = field(hash=False)
54
+ version: str = field(hash=False)
55
+ tags: frozenset[str] = field(default_factory=frozenset, hash=False)
56
+ extra: MappingProxyType = field(
57
+ default_factory=lambda: MappingProxyType({}), hash=False
58
+ )
59
+
60
+ @classmethod
61
+ def from_protobuf(cls, protobuf: WorkerInfoProtobuf) -> WorkerInfo:
62
+ """Create a WorkerInfo instance from a protobuf message.
63
+
64
+ :param protobuf:
65
+ The protobuf WorkerInfo message to deserialize.
66
+ :returns:
67
+ A new WorkerInfo instance with data from the protobuf message.
68
+ :raises ValueError:
69
+ If the UID in the protobuf message is not a valid UUID.
70
+ """
71
+
72
+ return cls(
73
+ uid=uuid.UUID(protobuf.uid),
74
+ host=protobuf.host,
75
+ port=protobuf.port if protobuf.port != 0 else None,
76
+ pid=protobuf.pid,
77
+ version=protobuf.version,
78
+ tags=frozenset(protobuf.tags),
79
+ extra=MappingProxyType(dict(protobuf.extra)),
80
+ )
81
+
82
+ def to_protobuf(self) -> WorkerInfoProtobuf:
83
+ """Convert this WorkerInfo instance to a protobuf message.
84
+
85
+ :returns:
86
+ A protobuf WorkerInfo message containing this instance's data.
87
+ """
88
+
89
+ return WorkerInfoProtobuf(
90
+ uid=str(self.uid),
91
+ host=self.host,
92
+ port=self.port if self.port is not None else 0,
93
+ pid=self.pid,
94
+ version=self.version,
95
+ tags=list(self.tags),
96
+ extra=dict(self.extra),
97
+ )
98
+
99
+
100
+ # public
101
+ DiscoveryEventType: TypeAlias = Literal[
102
+ "worker-added", "worker-dropped", "worker-updated"
103
+ ]
104
+
105
+
106
+ # public
107
+ @dataclass
108
+ class DiscoveryEvent:
109
+ """Event representing a change in worker availability.
110
+
111
+ Emitted by discovery services when workers are added, updated, or
112
+ removed from the pool. Contains both the event type and the
113
+ affected worker's information.
114
+
115
+ :param type:
116
+ The type of discovery event.
117
+ :param worker_info:
118
+ Information about the worker that triggered the event.
119
+ """
120
+
121
+ type: DiscoveryEventType
122
+ worker_info: WorkerInfo
123
+
124
+
125
+ # public
126
+ @runtime_checkable
127
+ class DiscoveryPublisherLike(Protocol):
128
+ """Protocol for publishing worker discovery events.
129
+
130
+ Implementations must provide a publish method that broadcasts
131
+ worker lifecycle events (added, updated, dropped) to subscribers.
132
+ """
133
+
134
+ async def publish(self, type: DiscoveryEventType, worker_info: WorkerInfo) -> None:
135
+ """Publish a worker discovery event.
136
+
137
+ :param type:
138
+ The type of discovery event.
139
+ :param worker_info:
140
+ Information about the worker.
141
+ """
142
+ ...
143
+
144
+
145
+ # public
146
+ @runtime_checkable
147
+ class DiscoverySubscriberLike(Protocol):
148
+ """Protocol for receiving worker discovery events.
149
+
150
+ Implementations must provide an async iterator that yields
151
+ discovery events as workers join, leave, or update their status.
152
+ """
153
+
154
+ def __aiter__(self) -> AsyncIterator[DiscoveryEvent]:
155
+ """Return an async iterator of discovery events.
156
+
157
+ :returns:
158
+ An async iterator yielding discovery events.
159
+ """
160
+ ...
161
+
162
+
163
+ # public
164
+ @runtime_checkable
165
+ class DiscoveryLike(Protocol):
166
+ """Protocol for complete discovery service implementations.
167
+
168
+ Defines the interface for discovery services that provide both
169
+ publishing and subscribing capabilities. Implementations must
170
+ expose publisher and subscriber components and support filtered
171
+ subscriptions.
172
+ """
173
+
174
+ @property
175
+ def publisher(self) -> DiscoveryPublisherLike:
176
+ """Get the publisher component.
177
+
178
+ :returns:
179
+ A publisher instance for broadcasting events.
180
+ """
181
+ ...
182
+
183
+ @property
184
+ def subscriber(self) -> DiscoverySubscriberLike:
185
+ """Get the default subscriber component.
186
+
187
+ :returns:
188
+ A subscriber instance for receiving events.
189
+ """
190
+ ...
191
+
192
+ def subscribe(
193
+ self, filter: PredicateFunction | None = None
194
+ ) -> DiscoverySubscriberLike:
195
+ """Create a filtered subscriber.
196
+
197
+ :param filter:
198
+ Optional predicate to filter discovered workers.
199
+ :returns:
200
+ A subscriber instance for receiving filtered events.
201
+ """
202
+ ...
203
+
204
+
205
+ # public
206
+ class Discovery(ABC):
207
+ """Abstract base class for worker discovery implementations.
208
+
209
+ Provides the foundation for pluggable discovery mechanisms that
210
+ enable workers to find and communicate with each other. Concrete
211
+ implementations handle the specifics of service registration and
212
+ discovery based on the deployment environment (LAN, local, cloud).
213
+
214
+ Subclasses must implement the publisher and subscriber properties,
215
+ as well as the subscribe method for filtered subscriptions.
216
+ """
217
+
218
+ @property
219
+ @abstractmethod
220
+ def publisher(self) -> DiscoveryPublisherLike:
221
+ """Get the publisher component.
222
+
223
+ :returns:
224
+ A publisher instance for broadcasting events.
225
+ """
226
+ ...
227
+
228
+ @property
229
+ @abstractmethod
230
+ def subscriber(self) -> DiscoverySubscriberLike:
231
+ """Get the default subscriber component.
232
+
233
+ :returns:
234
+ A subscriber instance for receiving events.
235
+ """
236
+ ...
237
+
238
+ @abstractmethod
239
+ def subscribe(
240
+ self, filter: PredicateFunction | None = None
241
+ ) -> DiscoverySubscriberLike:
242
+ """Create a filtered subscriber.
243
+
244
+ :param filter:
245
+ Optional predicate to filter discovered workers.
246
+ :returns:
247
+ A subscriber instance for receiving filtered events.
248
+ """
249
+ ...