digitalkin 0.2.12__py3-none-any.whl → 0.2.13__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.
- digitalkin/__version__.py +1 -1
- digitalkin/grpc_servers/_base_server.py +15 -17
- digitalkin/grpc_servers/module_server.py +9 -10
- digitalkin/grpc_servers/module_servicer.py +107 -85
- digitalkin/grpc_servers/registry_server.py +3 -6
- digitalkin/grpc_servers/registry_servicer.py +18 -19
- digitalkin/grpc_servers/utils/grpc_client_wrapper.py +3 -5
- digitalkin/logger.py +45 -1
- digitalkin/models/module/module.py +1 -0
- digitalkin/modules/_base_module.py +44 -5
- digitalkin/modules/job_manager/base_job_manager.py +139 -0
- digitalkin/modules/job_manager/job_manager_models.py +44 -0
- digitalkin/modules/job_manager/single_job_manager.py +218 -0
- digitalkin/modules/job_manager/taskiq_broker.py +173 -0
- digitalkin/modules/job_manager/taskiq_job_manager.py +213 -0
- digitalkin/services/cost/default_cost.py +8 -4
- digitalkin/services/cost/grpc_cost.py +15 -7
- digitalkin/services/filesystem/default_filesystem.py +2 -4
- digitalkin/services/filesystem/grpc_filesystem.py +8 -5
- digitalkin/services/setup/__init__.py +1 -0
- digitalkin/services/setup/default_setup.py +10 -12
- digitalkin/services/setup/grpc_setup.py +8 -10
- digitalkin/services/storage/default_storage.py +11 -5
- digitalkin/services/storage/grpc_storage.py +23 -8
- digitalkin/utils/arg_parser.py +5 -48
- digitalkin/utils/development_mode_action.py +51 -0
- {digitalkin-0.2.12.dist-info → digitalkin-0.2.13.dist-info}/METADATA +42 -11
- {digitalkin-0.2.12.dist-info → digitalkin-0.2.13.dist-info}/RECORD +35 -28
- {digitalkin-0.2.12.dist-info → digitalkin-0.2.13.dist-info}/WHEEL +1 -1
- modules/cpu_intensive_module.py +271 -0
- modules/minimal_llm_module.py +200 -56
- modules/storage_module.py +5 -6
- modules/text_transform_module.py +1 -1
- digitalkin/modules/job_manager.py +0 -177
- {digitalkin-0.2.12.dist-info → digitalkin-0.2.13.dist-info}/licenses/LICENSE +0 -0
- {digitalkin-0.2.12.dist-info → digitalkin-0.2.13.dist-info}/top_level.txt +0 -0
digitalkin/__version__.py
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
import abc
|
|
4
4
|
import asyncio
|
|
5
|
-
import logging
|
|
6
5
|
from collections.abc import Callable
|
|
7
6
|
from concurrent import futures
|
|
8
7
|
from pathlib import Path
|
|
@@ -20,8 +19,7 @@ from digitalkin.grpc_servers.utils.exceptions import (
|
|
|
20
19
|
)
|
|
21
20
|
from digitalkin.grpc_servers.utils.models import SecurityMode, ServerConfig, ServerMode
|
|
22
21
|
from digitalkin.grpc_servers.utils.types import GrpcServer, ServiceDescriptor, T
|
|
23
|
-
|
|
24
|
-
logger = logging.getLogger(__name__)
|
|
22
|
+
from digitalkin.logger import logger
|
|
25
23
|
|
|
26
24
|
|
|
27
25
|
class BaseServer(abc.ABC):
|
|
@@ -132,7 +130,7 @@ class BaseServer(abc.ABC):
|
|
|
132
130
|
# reflection queries with detailed service information
|
|
133
131
|
reflection.enable_server_reflection(service_names, self.server)
|
|
134
132
|
|
|
135
|
-
logger.
|
|
133
|
+
logger.debug("Added gRPC reflection service with services: %s", service_names)
|
|
136
134
|
except ImportError:
|
|
137
135
|
logger.warning("Could not enable reflection: grpcio-reflection package not installed")
|
|
138
136
|
except Exception as e:
|
|
@@ -165,7 +163,7 @@ class BaseServer(abc.ABC):
|
|
|
165
163
|
if service_name not in self._service_names:
|
|
166
164
|
self._service_names.append(service_name)
|
|
167
165
|
|
|
168
|
-
logger.
|
|
166
|
+
logger.debug("Added gRPC health checking service")
|
|
169
167
|
|
|
170
168
|
# Set all services as SERVING
|
|
171
169
|
for service_name in self._service_names:
|
|
@@ -255,7 +253,7 @@ class BaseServer(abc.ABC):
|
|
|
255
253
|
sync_server = cast("grpc.Server", server)
|
|
256
254
|
sync_server.add_secure_port(self.config.address, server_credentials)
|
|
257
255
|
|
|
258
|
-
logger.
|
|
256
|
+
logger.debug("Added secure port %s", self.config.address)
|
|
259
257
|
except Exception as e:
|
|
260
258
|
msg = f"Failed to configure secure port: {e}"
|
|
261
259
|
raise SecurityError(msg) from e
|
|
@@ -277,7 +275,7 @@ class BaseServer(abc.ABC):
|
|
|
277
275
|
sync_server = cast("grpc.Server", server)
|
|
278
276
|
sync_server.add_insecure_port(self.config.address)
|
|
279
277
|
|
|
280
|
-
logger.
|
|
278
|
+
logger.debug("Added insecure port %s", self.config.address)
|
|
281
279
|
except Exception as e:
|
|
282
280
|
msg = f"Failed to add insecure port: {e}"
|
|
283
281
|
raise ConfigurationError(msg) from e
|
|
@@ -301,7 +299,7 @@ class BaseServer(abc.ABC):
|
|
|
301
299
|
self._add_reflection()
|
|
302
300
|
|
|
303
301
|
# Start the server
|
|
304
|
-
logger.
|
|
302
|
+
logger.debug("Starting gRPC server on %s", self.config.address)
|
|
305
303
|
try:
|
|
306
304
|
if self.config.mode == ServerMode.ASYNC:
|
|
307
305
|
# For async server, use the event loop
|
|
@@ -314,7 +312,7 @@ class BaseServer(abc.ABC):
|
|
|
314
312
|
# For sync server, directly call start
|
|
315
313
|
sync_server = cast("grpc.Server", self.server)
|
|
316
314
|
sync_server.start()
|
|
317
|
-
logger.
|
|
315
|
+
logger.debug("✅ gRPC server started on %s", self.config.address)
|
|
318
316
|
except Exception as e:
|
|
319
317
|
logger.exception("❎ Error starting server")
|
|
320
318
|
msg = f"Failed to start server: {e}"
|
|
@@ -351,7 +349,7 @@ class BaseServer(abc.ABC):
|
|
|
351
349
|
self._add_reflection()
|
|
352
350
|
|
|
353
351
|
# Start the server
|
|
354
|
-
logger.
|
|
352
|
+
logger.debug("Starting gRPC server on %s", self.config.address)
|
|
355
353
|
try:
|
|
356
354
|
if self.config.mode == ServerMode.ASYNC:
|
|
357
355
|
await self._start_async()
|
|
@@ -359,7 +357,7 @@ class BaseServer(abc.ABC):
|
|
|
359
357
|
# For sync server in async context
|
|
360
358
|
sync_server = cast("grpc.Server", self.server)
|
|
361
359
|
sync_server.start()
|
|
362
|
-
logger.
|
|
360
|
+
logger.debug("✅ gRPC server started on %s", self.config.address)
|
|
363
361
|
except Exception as e:
|
|
364
362
|
logger.exception("❎ Error starting server")
|
|
365
363
|
msg = f"Failed to start server: {e}"
|
|
@@ -375,7 +373,7 @@ class BaseServer(abc.ABC):
|
|
|
375
373
|
logger.warning("Attempted to stop server, but no server is running")
|
|
376
374
|
return
|
|
377
375
|
|
|
378
|
-
logger.
|
|
376
|
+
logger.debug("Stopping gRPC server...")
|
|
379
377
|
if self.config.mode == ServerMode.ASYNC:
|
|
380
378
|
# We'll use a different approach that works whether we're in a running event loop or not
|
|
381
379
|
try:
|
|
@@ -392,13 +390,13 @@ class BaseServer(abc.ABC):
|
|
|
392
390
|
)
|
|
393
391
|
# Set server to None to avoid further operations
|
|
394
392
|
self.server = None
|
|
395
|
-
logger.
|
|
393
|
+
logger.debug("✅ gRPC server marked as stopped")
|
|
396
394
|
return
|
|
397
395
|
# If not in a running event loop, use run_until_complete
|
|
398
396
|
loop.run_until_complete(self._stop_async(grace))
|
|
399
397
|
except RuntimeError:
|
|
400
398
|
# Event loop issues - try with a new loop
|
|
401
|
-
logger.
|
|
399
|
+
logger.debug("Creating new event loop for shutdown")
|
|
402
400
|
try:
|
|
403
401
|
new_loop = asyncio.new_event_loop()
|
|
404
402
|
asyncio.set_event_loop(new_loop)
|
|
@@ -410,7 +408,7 @@ class BaseServer(abc.ABC):
|
|
|
410
408
|
sync_server = cast("grpc.Server", self.server)
|
|
411
409
|
sync_server.stop(grace=grace)
|
|
412
410
|
|
|
413
|
-
logger.
|
|
411
|
+
logger.debug("✅ gRPC server stopped")
|
|
414
412
|
self.server = None
|
|
415
413
|
|
|
416
414
|
async def _stop_async(self, grace: float | None = None) -> None:
|
|
@@ -437,7 +435,7 @@ class BaseServer(abc.ABC):
|
|
|
437
435
|
logger.warning("Attempted to stop server, but no server is running")
|
|
438
436
|
return
|
|
439
437
|
|
|
440
|
-
logger.
|
|
438
|
+
logger.debug("Stopping gRPC server asynchronously...")
|
|
441
439
|
if self.config.mode == ServerMode.ASYNC:
|
|
442
440
|
await self._stop_async(grace)
|
|
443
441
|
else:
|
|
@@ -445,7 +443,7 @@ class BaseServer(abc.ABC):
|
|
|
445
443
|
sync_server = cast("grpc.Server", self.server)
|
|
446
444
|
sync_server.stop(grace=grace)
|
|
447
445
|
|
|
448
|
-
logger.
|
|
446
|
+
logger.debug("✅ gRPC server stopped")
|
|
449
447
|
self.server = None
|
|
450
448
|
|
|
451
449
|
def wait_for_termination(self) -> None:
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
"""Module gRPC server implementation for DigitalKin."""
|
|
2
2
|
|
|
3
|
-
import logging
|
|
4
3
|
from pathlib import Path
|
|
5
4
|
import uuid
|
|
6
5
|
|
|
@@ -25,8 +24,7 @@ from digitalkin_proto.digitalkin.module_registry.v2 import (
|
|
|
25
24
|
module_registry_service_pb2_grpc,
|
|
26
25
|
registration_pb2,
|
|
27
26
|
)
|
|
28
|
-
|
|
29
|
-
logger = logging.getLogger(__name__)
|
|
27
|
+
from digitalkin.logger import logger
|
|
30
28
|
|
|
31
29
|
|
|
32
30
|
class ModuleServer(BaseServer):
|
|
@@ -70,14 +68,14 @@ class ModuleServer(BaseServer):
|
|
|
70
68
|
msg = "Server must be created before registering servicers"
|
|
71
69
|
raise RuntimeError(msg)
|
|
72
70
|
|
|
73
|
-
logger.
|
|
71
|
+
logger.debug("Registering module servicer for %s", self.module_class.__name__)
|
|
74
72
|
self.module_servicer = ModuleServicer(self.module_class)
|
|
75
73
|
self.register_servicer(
|
|
76
74
|
self.module_servicer,
|
|
77
75
|
module_service_pb2_grpc.add_ModuleServiceServicer_to_server,
|
|
78
76
|
service_descriptor=module_service_pb2.DESCRIPTOR,
|
|
79
77
|
)
|
|
80
|
-
logger.
|
|
78
|
+
logger.debug("Registered Module servicer")
|
|
81
79
|
|
|
82
80
|
def start(self) -> None:
|
|
83
81
|
"""Start the module server and register with the registry if configured."""
|
|
@@ -115,6 +113,7 @@ class ModuleServer(BaseServer):
|
|
|
115
113
|
logger.critical(
|
|
116
114
|
"Setup post init started with config: %s", self.client_config
|
|
117
115
|
)
|
|
116
|
+
await self.module_servicer.job_manager._start()
|
|
118
117
|
self.module_servicer.setup.__post_init__(self.client_config)
|
|
119
118
|
|
|
120
119
|
def stop(self, grace: float | None = None) -> None:
|
|
@@ -134,7 +133,7 @@ class ModuleServer(BaseServer):
|
|
|
134
133
|
Raises:
|
|
135
134
|
ServerError: If communication with the registry server fails.
|
|
136
135
|
"""
|
|
137
|
-
logger.
|
|
136
|
+
logger.debug(
|
|
138
137
|
"Registering module with registry at %s",
|
|
139
138
|
self.server_config.registry_address,
|
|
140
139
|
)
|
|
@@ -172,7 +171,7 @@ class ModuleServer(BaseServer):
|
|
|
172
171
|
|
|
173
172
|
try:
|
|
174
173
|
# Call the register method
|
|
175
|
-
logger.
|
|
174
|
+
logger.debug(
|
|
176
175
|
"Request sent to registry for module: %s:%s",
|
|
177
176
|
self.module_class.metadata["name"],
|
|
178
177
|
self.module_class.metadata["module_id"],
|
|
@@ -180,7 +179,7 @@ class ModuleServer(BaseServer):
|
|
|
180
179
|
response = stub.RegisterModule(request)
|
|
181
180
|
|
|
182
181
|
if response.success:
|
|
183
|
-
logger.
|
|
182
|
+
logger.debug("Module registered successfully")
|
|
184
183
|
else:
|
|
185
184
|
logger.error("Module registration failed")
|
|
186
185
|
except grpc.RpcError:
|
|
@@ -193,7 +192,7 @@ class ModuleServer(BaseServer):
|
|
|
193
192
|
Raises:
|
|
194
193
|
ServerError: If communication with the registry server fails.
|
|
195
194
|
"""
|
|
196
|
-
logger.
|
|
195
|
+
logger.debug(
|
|
197
196
|
"Deregistering module from registry at %s",
|
|
198
197
|
self.server_config.registry_address,
|
|
199
198
|
)
|
|
@@ -214,7 +213,7 @@ class ModuleServer(BaseServer):
|
|
|
214
213
|
response = stub.DeregisterModule(request)
|
|
215
214
|
|
|
216
215
|
if response.success:
|
|
217
|
-
logger.
|
|
216
|
+
logger.debug("Module deregistered successfull")
|
|
218
217
|
else:
|
|
219
218
|
logger.error("Module deregistration failed")
|
|
220
219
|
except grpc.RpcError:
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"""Module servicer implementation for DigitalKin."""
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
import logging
|
|
3
|
+
from argparse import ArgumentParser, Namespace
|
|
5
4
|
from collections.abc import AsyncGenerator
|
|
6
5
|
from typing import Any
|
|
7
6
|
|
|
@@ -15,19 +14,20 @@ from digitalkin_proto.digitalkin.module.v2 import (
|
|
|
15
14
|
from google.protobuf import json_format, struct_pb2
|
|
16
15
|
|
|
17
16
|
from digitalkin.grpc_servers.utils.exceptions import ServicerError
|
|
18
|
-
from digitalkin.
|
|
17
|
+
from digitalkin.logger import logger
|
|
19
18
|
from digitalkin.models.module.module import ModuleStatus
|
|
20
19
|
from digitalkin.modules._base_module import BaseModule
|
|
21
|
-
from digitalkin.modules.job_manager import
|
|
20
|
+
from digitalkin.modules.job_manager.base_job_manager import BaseJobManager
|
|
21
|
+
from digitalkin.modules.job_manager.job_manager_models import JobManagerMode
|
|
22
22
|
from digitalkin.services.services_models import ServicesMode
|
|
23
23
|
from digitalkin.services.setup.default_setup import DefaultSetup
|
|
24
24
|
from digitalkin.services.setup.grpc_setup import GrpcSetup
|
|
25
25
|
from digitalkin.services.setup.setup_strategy import SetupStrategy
|
|
26
|
+
from digitalkin.utils.arg_parser import ArgParser
|
|
27
|
+
from digitalkin.utils.development_mode_action import DevelopmentModeMappingAction
|
|
26
28
|
|
|
27
|
-
logger = logging.getLogger(__name__)
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer):
|
|
30
|
+
class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer, ArgParser):
|
|
31
31
|
"""Implementation of the ModuleService.
|
|
32
32
|
|
|
33
33
|
This servicer handles interactions with a DigitalKin module.
|
|
@@ -37,7 +37,31 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer):
|
|
|
37
37
|
active_jobs: Dictionary tracking active module jobs.
|
|
38
38
|
"""
|
|
39
39
|
|
|
40
|
+
args: Namespace
|
|
40
41
|
setup: SetupStrategy
|
|
42
|
+
job_manager: BaseJobManager
|
|
43
|
+
|
|
44
|
+
def _add_parser_args(self, parser: ArgumentParser) -> None:
|
|
45
|
+
super()._add_parser_args(parser)
|
|
46
|
+
parser.add_argument(
|
|
47
|
+
"-d",
|
|
48
|
+
"--dev-mode",
|
|
49
|
+
env_var="SERVICE_MODE",
|
|
50
|
+
choices=ServicesMode.__members__,
|
|
51
|
+
default="local",
|
|
52
|
+
action=DevelopmentModeMappingAction,
|
|
53
|
+
dest="services_mode",
|
|
54
|
+
help="Define Module Service configurations for endpoints",
|
|
55
|
+
)
|
|
56
|
+
parser.add_argument(
|
|
57
|
+
"-jm",
|
|
58
|
+
"--job-manager",
|
|
59
|
+
type=JobManagerMode,
|
|
60
|
+
choices=list(JobManagerMode),
|
|
61
|
+
default=JobManagerMode.SINGLE,
|
|
62
|
+
dest="job_manager_mode",
|
|
63
|
+
help="Define Module job manager configurations for load balancing",
|
|
64
|
+
)
|
|
41
65
|
|
|
42
66
|
def __init__(self, module_class: type[BaseModule]) -> None:
|
|
43
67
|
"""Initialize the module servicer.
|
|
@@ -46,15 +70,16 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer):
|
|
|
46
70
|
module_class: The module type to serve.
|
|
47
71
|
"""
|
|
48
72
|
super().__init__()
|
|
49
|
-
self.queue: asyncio.Queue = asyncio.Queue()
|
|
50
73
|
self.module_class = module_class
|
|
51
|
-
|
|
52
|
-
self.
|
|
74
|
+
job_manager_class = self.args.job_manager_mode.get_manager_class()
|
|
75
|
+
self.job_manager = job_manager_class(module_class, self.args.services_mode)
|
|
53
76
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
77
|
+
logger.debug(
|
|
78
|
+
"ModuleServicer initialized with job manager: %s | %s",
|
|
79
|
+
self.args.job_manager_mode,
|
|
80
|
+
self.job_manager,
|
|
81
|
+
)
|
|
82
|
+
self.setup = GrpcSetup() if self.args.services_mode == ServicesMode.REMOTE else DefaultSetup()
|
|
58
83
|
|
|
59
84
|
async def StartModule( # noqa: N802
|
|
60
85
|
self,
|
|
@@ -87,47 +112,45 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer):
|
|
|
87
112
|
if not setup_data_class:
|
|
88
113
|
msg = "No setup data returned."
|
|
89
114
|
raise ServicerError(msg)
|
|
90
|
-
|
|
115
|
+
|
|
91
116
|
setup_data = self.module_class.create_setup_model(setup_data_class.current_setup_version.content)
|
|
92
117
|
|
|
93
|
-
#
|
|
94
|
-
|
|
95
|
-
result: tuple[str, BaseModule] = await self.job_manager.create_job(
|
|
118
|
+
# create a task to run the module in background
|
|
119
|
+
job_id = await self.job_manager.create_job(
|
|
96
120
|
input_data,
|
|
97
121
|
setup_data,
|
|
98
122
|
mission_id=request.mission_id,
|
|
99
123
|
setup_version_id=setup_data_class.current_setup_version.id,
|
|
100
|
-
callback=self.add_to_queue,
|
|
101
124
|
)
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
job_id=job_id
|
|
130
|
-
|
|
125
|
+
|
|
126
|
+
if job_id is None:
|
|
127
|
+
context.set_code(grpc.StatusCode.NOT_FOUND)
|
|
128
|
+
context.set_details("Failed to create module instance")
|
|
129
|
+
yield lifecycle_pb2.StartModuleResponse(success=False)
|
|
130
|
+
return
|
|
131
|
+
|
|
132
|
+
async with self.job_manager.generate_stream_consumer(job_id) as stream: # type: ignore
|
|
133
|
+
async for message in stream:
|
|
134
|
+
if message.get("error", None) is not None:
|
|
135
|
+
context.set_code(message["error"]["code"])
|
|
136
|
+
context.set_details(message["error"]["error_message"])
|
|
137
|
+
yield lifecycle_pb2.StartModuleResponse(success=False, job_id=job_id)
|
|
138
|
+
break
|
|
139
|
+
|
|
140
|
+
if message.get("exception", None) is not None:
|
|
141
|
+
logger.error("Error in output_data")
|
|
142
|
+
context.set_code(message["short_description"])
|
|
143
|
+
context.set_details(message["exception"])
|
|
144
|
+
yield lifecycle_pb2.StartModuleResponse(success=False, job_id=job_id)
|
|
145
|
+
break
|
|
146
|
+
|
|
147
|
+
if message.get("code", None) is not None and message.get("code") == "__END_OF_STREAM__":
|
|
148
|
+
yield lifecycle_pb2.StartModuleResponse(success=True, job_id=job_id)
|
|
149
|
+
break
|
|
150
|
+
|
|
151
|
+
proto = json_format.ParseDict(message, struct_pb2.Struct(), ignore_unknown_fields=True)
|
|
152
|
+
yield lifecycle_pb2.StartModuleResponse(success=True, output=proto, job_id=job_id)
|
|
153
|
+
logger.info("Job %s finished", job_id)
|
|
131
154
|
|
|
132
155
|
async def StopModule( # noqa: N802
|
|
133
156
|
self,
|
|
@@ -143,23 +166,20 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer):
|
|
|
143
166
|
Returns:
|
|
144
167
|
A response indicating success or failure.
|
|
145
168
|
"""
|
|
146
|
-
logger.
|
|
169
|
+
logger.debug("StopModule called for module: '%s'", self.module_class.__name__)
|
|
147
170
|
|
|
148
|
-
|
|
149
|
-
if
|
|
150
|
-
message = f"Job {job_id} not found"
|
|
171
|
+
response: bool = await self.job_manager.stop_module(request.job_id)
|
|
172
|
+
if not response:
|
|
173
|
+
message = f"Job {request.job_id} not found"
|
|
151
174
|
logger.warning(message)
|
|
152
175
|
context.set_code(grpc.StatusCode.NOT_FOUND)
|
|
153
176
|
context.set_details(message)
|
|
154
177
|
return lifecycle_pb2.StopModuleResponse(success=False)
|
|
155
178
|
|
|
156
|
-
|
|
157
|
-
await self.job_manager.modules[job_id].stop()
|
|
158
|
-
|
|
159
|
-
logger.info("Job %s stopped successfully", job_id)
|
|
179
|
+
logger.debug("Job %s stopped successfully", request.job_id)
|
|
160
180
|
return lifecycle_pb2.StopModuleResponse(success=True)
|
|
161
181
|
|
|
162
|
-
def GetModuleStatus( # noqa: N802
|
|
182
|
+
async def GetModuleStatus( # noqa: N802
|
|
163
183
|
self,
|
|
164
184
|
request: monitoring_pb2.GetModuleStatusRequest,
|
|
165
185
|
context: grpc.ServicerContext,
|
|
@@ -173,33 +193,33 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer):
|
|
|
173
193
|
Returns:
|
|
174
194
|
A response with the module status.
|
|
175
195
|
"""
|
|
176
|
-
logger.
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
if request.job_id not in self.job_manager.modules:
|
|
181
|
-
message = f"Job {request.job_id} not found"
|
|
182
|
-
logger.warning(message)
|
|
183
|
-
context.set_code(grpc.StatusCode.NOT_FOUND)
|
|
184
|
-
context.set_details(message)
|
|
185
|
-
return monitoring_pb2.GetModuleStatusResponse()
|
|
186
|
-
|
|
187
|
-
status = self.job_manager.modules[request.job_id].status
|
|
188
|
-
logger.info("Job %s status: '%s'", request.job_id, status)
|
|
196
|
+
logger.debug("GetModuleStatus called for module: '%s'", self.module_class.__name__)
|
|
197
|
+
|
|
198
|
+
if not request.job_id:
|
|
199
|
+
logger.debug("Job %s status: '%s'", request.job_id, ModuleStatus.NOT_FOUND)
|
|
189
200
|
return monitoring_pb2.GetModuleStatusResponse(
|
|
190
|
-
success=
|
|
191
|
-
status=
|
|
201
|
+
success=False,
|
|
202
|
+
status=ModuleStatus.NOT_FOUND.name,
|
|
192
203
|
job_id=request.job_id,
|
|
193
204
|
)
|
|
194
205
|
|
|
195
|
-
|
|
206
|
+
status = await self.job_manager.get_module_status(request.job_id)
|
|
207
|
+
|
|
208
|
+
if status is None:
|
|
209
|
+
message = f"Job {request.job_id} not found"
|
|
210
|
+
logger.warning(message)
|
|
211
|
+
context.set_code(grpc.StatusCode.NOT_FOUND)
|
|
212
|
+
context.set_details(message)
|
|
213
|
+
return monitoring_pb2.GetModuleStatusResponse()
|
|
214
|
+
|
|
215
|
+
logger.debug("Job %s status: '%s'", request.job_id, status)
|
|
196
216
|
return monitoring_pb2.GetModuleStatusResponse(
|
|
197
|
-
success=
|
|
198
|
-
status=
|
|
217
|
+
success=True,
|
|
218
|
+
status=status.name,
|
|
199
219
|
job_id=request.job_id,
|
|
200
220
|
)
|
|
201
221
|
|
|
202
|
-
def GetModuleJobs( # noqa: N802
|
|
222
|
+
async def GetModuleJobs( # noqa: N802
|
|
203
223
|
self,
|
|
204
224
|
request: monitoring_pb2.GetModuleJobsRequest, # noqa: ARG002
|
|
205
225
|
context: grpc.ServicerContext, # noqa: ARG002
|
|
@@ -213,20 +233,22 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer):
|
|
|
213
233
|
Returns:
|
|
214
234
|
A response with information about active jobs.
|
|
215
235
|
"""
|
|
216
|
-
logger.
|
|
236
|
+
logger.debug("GetModuleJobs called for module: '%s'", self.module_class.__name__)
|
|
237
|
+
|
|
238
|
+
modules = await self.job_manager.list_modules()
|
|
217
239
|
|
|
218
240
|
# Create job info objects for each active job
|
|
219
241
|
return monitoring_pb2.GetModuleJobsResponse(
|
|
220
242
|
jobs=[
|
|
221
243
|
monitoring_pb2.JobInfo(
|
|
222
244
|
job_id=job_id,
|
|
223
|
-
job_status=job_data
|
|
245
|
+
job_status=job_data["status"].name,
|
|
224
246
|
)
|
|
225
|
-
for job_id, job_data in
|
|
247
|
+
for job_id, job_data in modules.items()
|
|
226
248
|
],
|
|
227
249
|
)
|
|
228
250
|
|
|
229
|
-
def GetModuleInput( # noqa: N802
|
|
251
|
+
async def GetModuleInput( # noqa: N802
|
|
230
252
|
self,
|
|
231
253
|
request: information_pb2.GetModuleInputRequest,
|
|
232
254
|
context: grpc.ServicerContext,
|
|
@@ -240,7 +262,7 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer):
|
|
|
240
262
|
Returns:
|
|
241
263
|
A response with the module's input schema.
|
|
242
264
|
"""
|
|
243
|
-
logger.
|
|
265
|
+
logger.debug("GetModuleInput called for module: '%s'", self.module_class.__name__)
|
|
244
266
|
|
|
245
267
|
# Get input schema if available
|
|
246
268
|
try:
|
|
@@ -262,7 +284,7 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer):
|
|
|
262
284
|
input_schema=input_format_struct,
|
|
263
285
|
)
|
|
264
286
|
|
|
265
|
-
def GetModuleOutput( # noqa: N802
|
|
287
|
+
async def GetModuleOutput( # noqa: N802
|
|
266
288
|
self,
|
|
267
289
|
request: information_pb2.GetModuleOutputRequest,
|
|
268
290
|
context: grpc.ServicerContext,
|
|
@@ -276,7 +298,7 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer):
|
|
|
276
298
|
Returns:
|
|
277
299
|
A response with the module's output schema.
|
|
278
300
|
"""
|
|
279
|
-
logger.
|
|
301
|
+
logger.debug("GetModuleOutput called for module: '%s'", self.module_class.__name__)
|
|
280
302
|
|
|
281
303
|
# Get output schema if available
|
|
282
304
|
try:
|
|
@@ -298,7 +320,7 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer):
|
|
|
298
320
|
output_schema=output_format_struct,
|
|
299
321
|
)
|
|
300
322
|
|
|
301
|
-
def GetModuleSetup( # noqa: N802
|
|
323
|
+
async def GetModuleSetup( # noqa: N802
|
|
302
324
|
self,
|
|
303
325
|
request: information_pb2.GetModuleSetupRequest,
|
|
304
326
|
context: grpc.ServicerContext,
|
|
@@ -312,7 +334,7 @@ class ModuleServicer(module_service_pb2_grpc.ModuleServiceServicer):
|
|
|
312
334
|
Returns:
|
|
313
335
|
A response with the module's setup information.
|
|
314
336
|
"""
|
|
315
|
-
logger.
|
|
337
|
+
logger.debug("GetModuleSetup called for module: '%s'", self.module_class.__name__)
|
|
316
338
|
|
|
317
339
|
# Get setup schema if available
|
|
318
340
|
try:
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
"""Registry gRPC server implementation for DigitalKin."""
|
|
2
2
|
|
|
3
|
-
import logging
|
|
4
|
-
|
|
5
3
|
from digitalkin_proto.digitalkin.module_registry.v2 import (
|
|
6
4
|
module_registry_service_pb2,
|
|
7
5
|
module_registry_service_pb2_grpc,
|
|
@@ -10,8 +8,7 @@ from digitalkin_proto.digitalkin.module_registry.v2 import (
|
|
|
10
8
|
from digitalkin.grpc_servers._base_server import BaseServer
|
|
11
9
|
from digitalkin.grpc_servers.registry_servicer import RegistryModule, RegistryServicer
|
|
12
10
|
from digitalkin.grpc_servers.utils.models import RegistryServerConfig
|
|
13
|
-
|
|
14
|
-
logger = logging.getLogger(__name__)
|
|
11
|
+
from digitalkin.logger import logger
|
|
15
12
|
|
|
16
13
|
|
|
17
14
|
class RegistryServer(BaseServer):
|
|
@@ -48,14 +45,14 @@ class RegistryServer(BaseServer):
|
|
|
48
45
|
msg = "Server must be created before registering servicers"
|
|
49
46
|
raise RuntimeError(msg)
|
|
50
47
|
|
|
51
|
-
logger.
|
|
48
|
+
logger.debug("Registering registry servicer")
|
|
52
49
|
self.registry_servicer = RegistryServicer()
|
|
53
50
|
self.register_servicer(
|
|
54
51
|
self.registry_servicer,
|
|
55
52
|
module_registry_service_pb2_grpc.add_ModuleRegistryServiceServicer_to_server,
|
|
56
53
|
service_descriptor=module_registry_service_pb2.DESCRIPTOR,
|
|
57
54
|
)
|
|
58
|
-
logger.
|
|
55
|
+
logger.debug("Registered registry servicer")
|
|
59
56
|
|
|
60
57
|
def get_registered_modules(self) -> list[RegistryModule]:
|
|
61
58
|
"""Get a list of all registered modules.
|