manta-node 0.5b0.dev9__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.
- manta_node/__init__.py +5 -0
- manta_node/__main__.py +57 -0
- manta_node/cli/__init__.py +6 -0
- manta_node/cli/commands/__init__.py +21 -0
- manta_node/cli/commands/cluster.py +419 -0
- manta_node/cli/commands/config.py +490 -0
- manta_node/cli/commands/logs.py +168 -0
- manta_node/cli/commands/start.py +459 -0
- manta_node/cli/commands/status.py +204 -0
- manta_node/cli/commands/stop.py +253 -0
- manta_node/cli/config_manager.py +139 -0
- manta_node/cli/main.py +133 -0
- manta_node/cli/version.py +106 -0
- manta_node/domain/__init__.py +8 -0
- manta_node/domain/task_lifecycle.py +83 -0
- manta_node/infrastructure/__init__.py +13 -0
- manta_node/infrastructure/config/__init__.py +31 -0
- manta_node/infrastructure/config/node_config_manager.py +918 -0
- manta_node/infrastructure/container/__init__.py +9 -0
- manta_node/infrastructure/container/docker_adapter.py +253 -0
- manta_node/infrastructure/container/manager.py +536 -0
- manta_node/infrastructure/filesystem/__init__.py +7 -0
- manta_node/infrastructure/filesystem/dataset_manager.py +469 -0
- manta_node/infrastructure/grpc/__init__.py +11 -0
- manta_node/infrastructure/grpc/client.py +373 -0
- manta_node/infrastructure/grpc/local_servicer.py +151 -0
- manta_node/infrastructure/grpc/world_servicer.py +284 -0
- manta_node/infrastructure/metrics/__init__.py +10 -0
- manta_node/infrastructure/metrics/collector.py +94 -0
- manta_node/infrastructure/metrics/metrics_collector.py +351 -0
- manta_node/infrastructure/mqtt/__init__.py +7 -0
- manta_node/infrastructure/mqtt/command_handler.py +315 -0
- manta_node/node_orchestrator.py +462 -0
- manta_node/task_manager.py +519 -0
- manta_node/tasks.py +272 -0
- manta_node/utils.py +52 -0
- manta_node-0.5b0.dev9.dist-info/METADATA +799 -0
- manta_node-0.5b0.dev9.dist-info/RECORD +42 -0
- manta_node-0.5b0.dev9.dist-info/WHEEL +5 -0
- manta_node-0.5b0.dev9.dist-info/entry_points.txt +2 -0
- manta_node-0.5b0.dev9.dist-info/licenses/LICENSE +683 -0
- manta_node-0.5b0.dev9.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
from logging import getLogger
|
|
2
|
+
from typing import AsyncIterator
|
|
3
|
+
|
|
4
|
+
from manta_common.build.common.results import (
|
|
5
|
+
ChunkResultValues,
|
|
6
|
+
GlobalTag,
|
|
7
|
+
GlobalUpdate,
|
|
8
|
+
GlobalValue,
|
|
9
|
+
Result,
|
|
10
|
+
ResultQuery,
|
|
11
|
+
)
|
|
12
|
+
from manta_common.build.common.system import EnvId, Ok
|
|
13
|
+
from manta_common.build.common.tasks import TaskScheduling, TaskUpdate
|
|
14
|
+
from manta_common.build.node.light_service import (
|
|
15
|
+
GetGlobalRequest,
|
|
16
|
+
LightResult,
|
|
17
|
+
LightResultQuery,
|
|
18
|
+
SetGlobalRequest,
|
|
19
|
+
WorldBase,
|
|
20
|
+
)
|
|
21
|
+
from manta_common.build.node.node_service import StopSwarmProcess
|
|
22
|
+
from manta_common.conversions import ID
|
|
23
|
+
from manta_common.decorators import catch_batch_errors, catch_streaming_errors
|
|
24
|
+
from manta_common.traces import Tracer
|
|
25
|
+
from ...tasks import TaskProgressions
|
|
26
|
+
from ..grpc.client import NodeClient
|
|
27
|
+
|
|
28
|
+
__all__ = ["WorldServicer"]
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class WorldServicer(WorldBase):
|
|
32
|
+
"""
|
|
33
|
+
World Servicer allows containers to access data stored in the Manager
|
|
34
|
+
|
|
35
|
+
Parameters
|
|
36
|
+
----------
|
|
37
|
+
|
|
38
|
+
Node ID
|
|
39
|
+
node_client : NodeClient
|
|
40
|
+
Node client
|
|
41
|
+
tasks : TaskProgressions
|
|
42
|
+
Task Progressions from Task Manager
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
__slots__ = ["tracer", "node_client", "tasks"]
|
|
46
|
+
|
|
47
|
+
def __init__(self, node_client: NodeClient, tasks: TaskProgressions):
|
|
48
|
+
self.tracer = Tracer(getLogger(__name__))
|
|
49
|
+
self.node_client = node_client
|
|
50
|
+
self.tasks = tasks
|
|
51
|
+
super().__init__()
|
|
52
|
+
|
|
53
|
+
def task_update(self, swarm_id: ID, task_id: ID) -> TaskUpdate:
|
|
54
|
+
"""
|
|
55
|
+
Convenient method to access task update from tasks
|
|
56
|
+
given a task ID
|
|
57
|
+
|
|
58
|
+
Parameters
|
|
59
|
+
----------
|
|
60
|
+
swarm_id : PairId
|
|
61
|
+
Swarm ID
|
|
62
|
+
task_id : PairId
|
|
63
|
+
Task ID
|
|
64
|
+
|
|
65
|
+
Returns
|
|
66
|
+
-------
|
|
67
|
+
TaskUpdate
|
|
68
|
+
Task Update
|
|
69
|
+
"""
|
|
70
|
+
return self.tasks[(swarm_id.tid, task_id.tid)].task_update
|
|
71
|
+
|
|
72
|
+
@catch_streaming_errors
|
|
73
|
+
async def get_task_result(
|
|
74
|
+
self, light_request: LightResultQuery
|
|
75
|
+
) -> AsyncIterator[ChunkResultValues]:
|
|
76
|
+
"""
|
|
77
|
+
Get the swarm results
|
|
78
|
+
|
|
79
|
+
Parameters
|
|
80
|
+
----------
|
|
81
|
+
request : LightResultQuery
|
|
82
|
+
Result query from the container
|
|
83
|
+
|
|
84
|
+
Returns
|
|
85
|
+
-------
|
|
86
|
+
AsyncIterator[ChunkResultValues]
|
|
87
|
+
Result values
|
|
88
|
+
"""
|
|
89
|
+
task_id = ID(light_request.task_id)
|
|
90
|
+
swarm_id = ID(light_request.swarm_id)
|
|
91
|
+
task_update = self.task_update(swarm_id, task_id)
|
|
92
|
+
iteration = task_update.iteration
|
|
93
|
+
circular = task_update.circular
|
|
94
|
+
self.tracer.set_metadata(
|
|
95
|
+
task_id=task_id,
|
|
96
|
+
swarm_id=swarm_id,
|
|
97
|
+
iteration=iteration,
|
|
98
|
+
circular=circular,
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
async for chunk in self.node_client.get_task_result(
|
|
102
|
+
ResultQuery(
|
|
103
|
+
swarm_id=swarm_id.oid,
|
|
104
|
+
task_id=task_id.oid,
|
|
105
|
+
node_id=self.tracer.metadata.node_id,
|
|
106
|
+
iteration=iteration,
|
|
107
|
+
tag=light_request.tag,
|
|
108
|
+
size=light_request.size,
|
|
109
|
+
method=light_request.method,
|
|
110
|
+
)
|
|
111
|
+
):
|
|
112
|
+
self.tracer.set_metadata(
|
|
113
|
+
task_id=task_id,
|
|
114
|
+
swarm_id=swarm_id,
|
|
115
|
+
iteration=iteration,
|
|
116
|
+
circular=circular,
|
|
117
|
+
)
|
|
118
|
+
yield chunk
|
|
119
|
+
|
|
120
|
+
@catch_batch_errors
|
|
121
|
+
async def add_task_result(self, stream: AsyncIterator[LightResult]) -> Ok:
|
|
122
|
+
"""
|
|
123
|
+
Set a swarm result
|
|
124
|
+
|
|
125
|
+
Parameters
|
|
126
|
+
----------
|
|
127
|
+
request : LightResult
|
|
128
|
+
Result from the container
|
|
129
|
+
|
|
130
|
+
Returns
|
|
131
|
+
-------
|
|
132
|
+
Ok
|
|
133
|
+
Response
|
|
134
|
+
"""
|
|
135
|
+
|
|
136
|
+
async def stream_generator(
|
|
137
|
+
stream: AsyncIterator[LightResult],
|
|
138
|
+
) -> AsyncIterator[Result]:
|
|
139
|
+
async for light_request in stream:
|
|
140
|
+
task_id = ID(light_request.task_id)
|
|
141
|
+
swarm_id = ID(light_request.swarm_id)
|
|
142
|
+
task_update = self.task_update(swarm_id, task_id)
|
|
143
|
+
self.tracer.set_metadata(
|
|
144
|
+
task_id=task_id,
|
|
145
|
+
swarm_id=swarm_id,
|
|
146
|
+
iteration=task_update.iteration,
|
|
147
|
+
circular=task_update.circular,
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
yield Result(
|
|
151
|
+
swarm_id=swarm_id.oid,
|
|
152
|
+
task_id=task_id.oid,
|
|
153
|
+
node_id=self.tracer.metadata.node_id,
|
|
154
|
+
iteration=task_update.iteration,
|
|
155
|
+
tag=light_request.tag,
|
|
156
|
+
data=light_request.data,
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
return await self.node_client.add_task_result(stream_generator(stream))
|
|
160
|
+
|
|
161
|
+
@catch_streaming_errors
|
|
162
|
+
async def get_global(self, request: GetGlobalRequest) -> AsyncIterator[GlobalValue]:
|
|
163
|
+
"""
|
|
164
|
+
Set a swarm global value
|
|
165
|
+
|
|
166
|
+
Parameters
|
|
167
|
+
----------
|
|
168
|
+
request : GlobalTag
|
|
169
|
+
Task ID and global tag
|
|
170
|
+
|
|
171
|
+
Returns
|
|
172
|
+
-------
|
|
173
|
+
GlobalValue
|
|
174
|
+
Global value
|
|
175
|
+
"""
|
|
176
|
+
task_id = ID(request.task_id)
|
|
177
|
+
swarm_id = ID(request.swarm_id)
|
|
178
|
+
task_update = self.task_update(swarm_id, task_id)
|
|
179
|
+
circular = task_update.circular
|
|
180
|
+
iteration = task_update.iteration
|
|
181
|
+
|
|
182
|
+
async for chunk in self.node_client.get_global(
|
|
183
|
+
GlobalTag(swarm_id=swarm_id.oid, tag=request.tag)
|
|
184
|
+
):
|
|
185
|
+
self.tracer.set_metadata(
|
|
186
|
+
task_id=task_id,
|
|
187
|
+
swarm_id=swarm_id,
|
|
188
|
+
iteration=iteration,
|
|
189
|
+
circular=circular,
|
|
190
|
+
)
|
|
191
|
+
self.tracer.info(f"Received chunk for global of size {len(chunk.data)}")
|
|
192
|
+
yield chunk
|
|
193
|
+
|
|
194
|
+
@catch_batch_errors
|
|
195
|
+
async def set_global(self, stream: AsyncIterator[SetGlobalRequest]) -> Ok:
|
|
196
|
+
"""
|
|
197
|
+
Set a swarm result
|
|
198
|
+
|
|
199
|
+
Parameters
|
|
200
|
+
----------
|
|
201
|
+
request : SetGlobalRequest
|
|
202
|
+
Task ID, global tag and value
|
|
203
|
+
|
|
204
|
+
Returns
|
|
205
|
+
-------
|
|
206
|
+
Ok
|
|
207
|
+
Response
|
|
208
|
+
"""
|
|
209
|
+
|
|
210
|
+
async def stream_generator(
|
|
211
|
+
stream: AsyncIterator[SetGlobalRequest],
|
|
212
|
+
) -> AsyncIterator[GlobalUpdate]:
|
|
213
|
+
async for request in stream:
|
|
214
|
+
swarm_id = ID(request.swarm_id)
|
|
215
|
+
task_id = ID(request.task_id)
|
|
216
|
+
task_update = self.task_update(swarm_id, task_id)
|
|
217
|
+
self.tracer.set_metadata(
|
|
218
|
+
task_id=task_id,
|
|
219
|
+
swarm_id=swarm_id,
|
|
220
|
+
iteration=task_update.iteration,
|
|
221
|
+
circular=task_update.circular,
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
yield GlobalUpdate(
|
|
225
|
+
swarm_id=swarm_id.oid,
|
|
226
|
+
tag=request.tag,
|
|
227
|
+
data=request.data,
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
return await self.node_client.set_global(stream_generator(stream))
|
|
231
|
+
|
|
232
|
+
@catch_batch_errors
|
|
233
|
+
async def stop_swarm(self, request: EnvId) -> Ok:
|
|
234
|
+
"""
|
|
235
|
+
Stop the swarm
|
|
236
|
+
|
|
237
|
+
Parameters
|
|
238
|
+
----------
|
|
239
|
+
request : EnvId
|
|
240
|
+
Task ID
|
|
241
|
+
|
|
242
|
+
Returns
|
|
243
|
+
-------
|
|
244
|
+
Ok
|
|
245
|
+
Response
|
|
246
|
+
"""
|
|
247
|
+
swarm_id = ID(request.swarm_id)
|
|
248
|
+
task_id = ID(request.task_id)
|
|
249
|
+
task_update = self.task_update(swarm_id, task_id)
|
|
250
|
+
self.tracer.set_metadata(
|
|
251
|
+
task_id=task_id,
|
|
252
|
+
swarm_id=swarm_id,
|
|
253
|
+
iteration=task_update.iteration,
|
|
254
|
+
circular=task_update.circular,
|
|
255
|
+
)
|
|
256
|
+
return await self.node_client.stop_swarm(
|
|
257
|
+
StopSwarmProcess(swarm_id=task_update.swarm_id)
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
@catch_batch_errors
|
|
261
|
+
async def schedule_task(self, light_request: TaskScheduling) -> Ok:
|
|
262
|
+
"""
|
|
263
|
+
Schedule a task
|
|
264
|
+
|
|
265
|
+
Parameters
|
|
266
|
+
----------
|
|
267
|
+
request : TaskScheduling
|
|
268
|
+
Task Scheduling from container
|
|
269
|
+
|
|
270
|
+
Returns
|
|
271
|
+
-------
|
|
272
|
+
Ok
|
|
273
|
+
Response
|
|
274
|
+
"""
|
|
275
|
+
swarm_id = ID(light_request.swarm_id)
|
|
276
|
+
task_id = ID(light_request.task_id)
|
|
277
|
+
task_update = self.task_update(swarm_id, task_id)
|
|
278
|
+
self.tracer.set_metadata(
|
|
279
|
+
task_id=task_id,
|
|
280
|
+
swarm_id=swarm_id,
|
|
281
|
+
iteration=task_update.iteration,
|
|
282
|
+
circular=task_update.circular,
|
|
283
|
+
)
|
|
284
|
+
return await self.node_client.schedule_task(light_request)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""Metrics infrastructure - System monitoring and data collection."""
|
|
2
|
+
|
|
3
|
+
from .collector import Collector
|
|
4
|
+
from .metrics_collector import GenericMetricsCollector, MetricsCollectorBase
|
|
5
|
+
|
|
6
|
+
__all__ = [
|
|
7
|
+
"Collector",
|
|
8
|
+
"GenericMetricsCollector",
|
|
9
|
+
"MetricsCollectorBase",
|
|
10
|
+
]
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
from manta_common.build.common.informations import NodeStatus, NodeStatusEnum
|
|
2
|
+
from manta_common.errors import (
|
|
3
|
+
MantaError,
|
|
4
|
+
MantaGRPCError,
|
|
5
|
+
MantaMQTTError,
|
|
6
|
+
MantaNodeError,
|
|
7
|
+
)
|
|
8
|
+
from manta_common.traces import Tracer
|
|
9
|
+
from ..filesystem.dataset_manager import DatasetManager
|
|
10
|
+
from ..grpc.client import NodeClient
|
|
11
|
+
from ..metrics.metrics_collector import MetricsCollectorBase
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Collector:
|
|
15
|
+
"""
|
|
16
|
+
Collector class to collect information from the node
|
|
17
|
+
|
|
18
|
+
Parameters
|
|
19
|
+
----------
|
|
20
|
+
tracer : Tracer
|
|
21
|
+
Tracer for the collector
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
tracer: Tracer
|
|
25
|
+
node_client: NodeClient
|
|
26
|
+
metrics_collector: MetricsCollectorBase
|
|
27
|
+
dataset_manager: DatasetManager
|
|
28
|
+
|
|
29
|
+
async def collect_information(self, payload: bytes):
|
|
30
|
+
"""
|
|
31
|
+
Send the node information to the Manager
|
|
32
|
+
|
|
33
|
+
Parameters
|
|
34
|
+
----------
|
|
35
|
+
payload : bytes
|
|
36
|
+
Payload
|
|
37
|
+
|
|
38
|
+
Raises
|
|
39
|
+
------
|
|
40
|
+
TaskManagerException
|
|
41
|
+
Exception when the method requested is not allowed
|
|
42
|
+
"""
|
|
43
|
+
try:
|
|
44
|
+
method = payload.decode("utf-8")
|
|
45
|
+
if method == "set_node_status":
|
|
46
|
+
await self.set_node_status()
|
|
47
|
+
elif method == "set_system_summary":
|
|
48
|
+
await self.set_system_summary()
|
|
49
|
+
elif method == "set_overviews":
|
|
50
|
+
await self.set_overviews()
|
|
51
|
+
else:
|
|
52
|
+
raise MantaMQTTError(
|
|
53
|
+
f"Not allowed method: {method}", metadata=self.tracer.metadata
|
|
54
|
+
)
|
|
55
|
+
except MantaGRPCError as e:
|
|
56
|
+
self.tracer.exception(f"Error when collecting information: {e}")
|
|
57
|
+
except MantaError as manta_error:
|
|
58
|
+
self.tracer.exception(repr(manta_error))
|
|
59
|
+
await self.node_client.send_error(manta_error)
|
|
60
|
+
except Exception as exc:
|
|
61
|
+
message = f"Error for collecting information: {repr(exc)}"
|
|
62
|
+
self.tracer.exception(message)
|
|
63
|
+
await self.node_client.send_error(
|
|
64
|
+
MantaNodeError(message, metadata=self.tracer.metadata)
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
async def set_node_status(self): # DEAD CODE
|
|
68
|
+
"""
|
|
69
|
+
Send the node information to the Manager
|
|
70
|
+
"""
|
|
71
|
+
self.tracer.info("Sending NodeInfo to the Manager")
|
|
72
|
+
await self.node_client.set_node_status(
|
|
73
|
+
NodeStatus(status=NodeStatusEnum.CONNECTED)
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
async def set_system_summary(self):
|
|
77
|
+
"""
|
|
78
|
+
Send the system information to the Manager
|
|
79
|
+
"""
|
|
80
|
+
self.tracer.info("Sending SystemInfo to the Manager")
|
|
81
|
+
metrics = await self.metrics_collector.collect_all_metrics()
|
|
82
|
+
await self.node_client.set_system_summary(metrics)
|
|
83
|
+
|
|
84
|
+
async def set_overviews(self):
|
|
85
|
+
"""
|
|
86
|
+
Send the data information to the Manager
|
|
87
|
+
"""
|
|
88
|
+
self.tracer.info("Sending DataInfo to the Manager")
|
|
89
|
+
|
|
90
|
+
# Refresh the dataset metadata before sending
|
|
91
|
+
self.dataset_manager.refresh()
|
|
92
|
+
|
|
93
|
+
# Use the dataset_manager to get the overview information
|
|
94
|
+
await self.node_client.set_overviews(self.dataset_manager.to_proto())
|