feat(robot-server, api): Implement RobotServerPyroResource providing proxies of server assets#21240
feat(robot-server, api): Implement RobotServerPyroResource providing proxies of server assets#21240CaseyBatten wants to merge 10 commits intoedgefrom
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## edge #21240 +/- ##
==========================================
- Coverage 56.97% 56.56% -0.42%
==========================================
Files 3978 3996 +18
Lines 326009 327714 +1705
Branches 46358 46690 +332
==========================================
- Hits 185744 185362 -382
- Misses 140046 142133 +2087
Partials 219 219
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
…ave abstract event loop
sfoster1
left a comment
There was a problem hiding this comment.
Looks great to me when tested! Got some inline things about style and spelling but fundamentally looks good!
| @@ -32,10 +33,12 @@ class DataFileSource(Enum): | |||
| GENERATED = "generated" | |||
|
|
|||
|
|
|||
| @dataclass(frozen=True) | |||
| class DataFileInfo: | |||
| #@dataclass(frozen=True) | |||
| @@ -116,6 +124,9 @@ async def clean_up_hardware(app_state: AppState) -> None: | |||
| _init_task_accessor.set_on(app_state, None) | |||
| _postinit_task_accessor.set_on(app_state, None) | |||
| _hw_api_accessor.set_on(app_state, None) | |||
| # NOTE: we erase the subprocess state, but do not run clean_up() on the subprocess. | |||
| # This is the responsibility of it's executing service. | |||
There was a problem hiding this comment.
| # This is the responsibility of it's executing service. | |
| # This is the responsibility of its executing service. |
| @@ -121,7 +121,8 @@ def __init__( | |||
| self._hardware_api = hardware_api | |||
| self._robot_type = robot_type | |||
| self._deck_type = deck_type | |||
| hardware_api.register_callback(_get_estop_listener(self)) | |||
| if not feature_flags.hardware_subprocess_enabled(): | |||
There was a problem hiding this comment.
this is one of the todos, right? maybe a good place for a todo comment
There was a problem hiding this comment.
I don't think this is a todo. This is just the preservation of the original callback registry assuming we are not in subprocess mode, for both runs and maintenance runs. I don't think this will ever go away unless we completely remove the old single-process software someday and do away with feature flags.
| @@ -193,7 +195,8 @@ def __init__( | |||
| self._run_process: Optional[subprocess.Popen[bytes]] = None | |||
| if feature_flags.protocol_subprocess_enabled(): | |||
| register_process_types() | |||
| hardware_api.register_callback(_get_hardware_listener(self)) | |||
| if not feature_flags.hardware_subprocess_enabled(): | |||
There was a problem hiding this comment.
Ditto here what I said in the reply above.
| @@ -95,6 +106,29 @@ async def _set_oem_mode_request(enable: bool, authorization_header: str | None) | |||
| return resp.status | |||
|
|
|||
|
|
|||
| async def _hardware_subprocess_transition(enable: bool, app_state: AppState) -> None: | |||
There was a problem hiding this comment.
whoa, this is fancy. i'd be okay just having this require a restart but it is pretty cool to have it be live
There was a problem hiding this comment.
The feasibility of this one will depend on the the systemd implementation for the OT3API. Once that work follows this up I'll be able to test linking the two, if it proves non-viable we'll go through with the restart approach.
|
|
||
|
|
||
| class RobotServerPyroResource: | ||
| """Class to represent the resources the robot-server hosts which can be provided over Pryo5. |
There was a problem hiding this comment.
| """Class to represent the resources the robot-server hosts which can be provided over Pryo5. | |
| """Class to represent the resources the robot-server hosts which can be provided over Pyro5. |
| with pyro.locate_ns() as ns: | ||
| while time.monotonic() - start_time < 60: | ||
| if RS_PYRONAME in ns.list(): | ||
| robot_server_proxy = pyro.Proxy(ns.list()[RS_PYRONAME]) # type: ignore[no-untyped-call] |
There was a problem hiding this comment.
maybe let's get a time.sleep(0.01) in here or something
| self._camera_provider: Optional[CameraProvider] = None | ||
| self._file_provider: Optional[FileProvider] = None | ||
|
|
||
| def _set_run_orchestorator_store( |
There was a problem hiding this comment.
| def _set_run_orchestorator_store( | |
| def _set_run_orchestrator_store( |
| """Set a provided RunOrchestratorStore as the active store to be used by the Robot Server's Pyro Resource.""" | ||
| robot_server_pyro_resource = robot_server_pyro_resource_accessor.get_from(app_state) | ||
| if robot_server_pyro_resource is not None: | ||
| robot_server_pyro_resource._set_run_orchestorator_store(run_orchestrator_store) |
There was a problem hiding this comment.
don't love calling underscore methods from over here
| @@ -81,6 +83,7 @@ class FlexHardwareControlInterface( | |||
| with some additional functionality and parameterization not supported on the OT-2. | |||
| """ | |||
|
|
|||
| @pyro_behavior(specialty_func=convert_type_to_instance, apply_local=False) | |||
There was a problem hiding this comment.
would prefer pulling the implementation out of this function if possible so this typing protocol remains free to import without involving more dependencies and import-time work
There was a problem hiding this comment.
Thats a good point. I'll see if theres a good place to create a pyro friendly alternative to somewhere else for the get_robot_type method.
Overview
Covers EXEC-2195
The bulk of this PRs logic gets us up to the point where if the hardware subprocess feature flag is enabled and a hardware subprocess is running, a run can "start" (without the protocol subprocess involved). This does not include the callback proxy for the doorwatcher needed after beginning a run (that will happen elsewhere).
TODO:
Test Plan and Hands on Testing
Changelog
Introduced bifurcated logic for initializing the hardware API depending on if the system is in "subprocess" mode
Introduced the RobotServerPyroResource which is spun up on app start.
Review requests
The use of feature flags is happening in a lot of places, should this be consolidated now or later?
Risk assessment
Medium - this is a pretty big one. It doesn't have to be "forever" code, especially the feature flag logic, but the core of the RobotServerPyroResource architecture will certainly remain. How do we feel about it?