-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Maestro] Add ability to install, start, and shutdown the Maestro dae…
…mon (#112)
- Loading branch information
Showing
26 changed files
with
949 additions
and
45 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,3 +11,5 @@ build | |
dist | ||
|
||
cond-out | ||
|
||
src/conductor/envs/resources/*.whl |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
syntax = "proto3"; | ||
|
||
package conductor; | ||
|
||
// Conductor's remote daemon service (Maestro). | ||
service Maestro { | ||
// A temporary RPC for testing purposes. | ||
rpc Ping(PingRequest) returns (PingResponse) {} | ||
|
||
// Tell the daemon to shut down. | ||
rpc Shutdown(ShutdownRequest) returns (ShutdownResponse) {} | ||
} | ||
|
||
message PingRequest { | ||
string message = 1; | ||
} | ||
|
||
message PingResponse { | ||
string message = 1; | ||
} | ||
|
||
message ShutdownRequest { | ||
string key = 1; | ||
} | ||
|
||
message ShutdownResponse { | ||
string message = 1; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
[MESSAGES CONTROL] | ||
disable=R,C | ||
enable=useless-suppression | ||
ignore-paths=src/conductor/envs/proto_gen/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import grpc | ||
from typing import Optional | ||
import conductor.envs.proto_gen.maestro_pb2 as pb | ||
import conductor.envs.proto_gen.maestro_pb2_grpc as maestro_grpc | ||
|
||
|
||
class MaestroGrpcClient: | ||
""" | ||
A wrapper over Maestro's gRPC stub, to simplify programmatic access through | ||
Python. | ||
This client is a thin wrapper over the gRPC stub. Methods on this client are | ||
synchronous. | ||
Usage: | ||
``` | ||
with MaestroGrpcClient(host, port) as client: | ||
# RPC calls here. | ||
pass | ||
``` | ||
""" | ||
|
||
def __init__(self, host: str, port: int): | ||
self._host = host | ||
self._port = port | ||
self._channel = None | ||
self._stub: Optional[maestro_grpc.MaestroStub] = None | ||
|
||
def __enter__(self): | ||
self.connect() | ||
return self | ||
|
||
def __exit__(self, exc_type, exc_value, traceback): | ||
self.close() | ||
|
||
def connect(self) -> None: | ||
self._channel = grpc.insecure_channel("{}:{}".format(self._host, self._port)) | ||
self._stub = maestro_grpc.MaestroStub(self._channel) | ||
|
||
def ping(self, message: str) -> str: | ||
assert self._stub is not None | ||
# pylint: disable-next=no-member | ||
msg = pb.PingRequest(message=message) | ||
return self._stub.Ping(msg).message | ||
|
||
def shutdown(self, key: str) -> str: | ||
assert self._stub is not None | ||
# pylint: disable-next=no-member | ||
msg = pb.ShutdownRequest(key=key) | ||
return self._stub.Shutdown(msg).message | ||
|
||
def close(self) -> None: | ||
assert self._stub is not None | ||
assert self._channel is not None | ||
self._stub = None | ||
self._channel.close() | ||
self._channel = None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import asyncio | ||
import logging | ||
import pathlib | ||
import subprocess | ||
from conductor.envs.maestro.interface import MaestroInterface | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class Maestro(MaestroInterface): | ||
""" | ||
Maestro is Conductor's remote daemon. It runs within a user-defined | ||
environment and executes tasks when requested by the main Conductor process. | ||
""" | ||
|
||
def __init__(self, maestro_root: pathlib.Path) -> None: | ||
self._maestro_root = maestro_root | ||
|
||
async def ping(self, message: str) -> str: | ||
logger.info("Received ping message: %s", message) | ||
result = subprocess.run(["uname", "-a"], capture_output=True, check=False) | ||
return result.stdout.decode("utf-8").strip() | ||
|
||
async def shutdown(self, key: str) -> str: | ||
logger.info("Received shutdown message with key %s", key) | ||
loop = asyncio.get_running_loop() | ||
loop.create_task(_orchestrate_shutdown()) | ||
return "OK" | ||
|
||
|
||
async def _orchestrate_shutdown() -> None: | ||
tasks = [t for t in asyncio.all_tasks() if t is not asyncio.current_task()] | ||
for task in tasks: | ||
task.cancel() | ||
await asyncio.gather(*tasks, return_exceptions=True) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import conductor.envs.proto_gen.maestro_pb2_grpc as rpc | ||
import conductor.envs.proto_gen.maestro_pb2 as pb | ||
from conductor.envs.maestro.interface import MaestroInterface | ||
|
||
# pylint: disable=no-member | ||
# See https://github.com/protocolbuffers/protobuf/issues/10372 | ||
|
||
# pylint: disable=invalid-overridden-method | ||
|
||
|
||
class MaestroGrpc(rpc.MaestroServicer): | ||
""" | ||
A shim layer used to implement Maestro's gRPC interface. | ||
""" | ||
|
||
def __init__(self, maestro: MaestroInterface) -> None: | ||
self._maestro = maestro | ||
|
||
async def Ping(self, request: pb.PingRequest, context) -> pb.PingResponse: | ||
response_message = await self._maestro.ping(request.message) | ||
return pb.PingResponse(message=response_message) | ||
|
||
async def Shutdown( | ||
self, request: pb.ShutdownRequest, context | ||
) -> pb.ShutdownResponse: | ||
response_message = await self._maestro.shutdown(request.key) | ||
return pb.ShutdownResponse(message=response_message) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
class MaestroInterface: | ||
""" | ||
Captures the RPC interface for Maestro. We use this interface to separate | ||
the gRPC implementation details from Maestro. | ||
""" | ||
|
||
async def ping(self, message: str) -> str: | ||
raise NotImplementedError | ||
|
||
async def shutdown(self, key: str) -> str: | ||
raise NotImplementedError |
Oops, something went wrong.