-
Notifications
You must be signed in to change notification settings - Fork 6
RPC Rework: With Var Renames #1143
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Conversation
…lueprint to be consistent with docs
…o jeff/blueprint/3
…imos into jeff/blueprint/6
Greptile OverviewGreptile SummaryThis PR implements a major refactoring of the RPC system with support for Spec-based module references. The core changes enable modules to declare dependencies on other modules via Protocol-based specifications rather than concrete types. Major Changes:
Critical Issue:
Confidence Score: 2/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant Client as Client Module
participant BP as Blueprint
participant MC as ModuleCoordinator
participant Calc as Calculator Module
participant RPC as LCMRPC
Note over Client,Calc: Module Definition Phase
Client->>Client: Define calc: ComputeSpec
Calc->>Calc: Implement @rpc methods
Note over BP,MC: Blueprint Build Phase
BP->>BP: Create _BlueprintAtom for each module
BP->>BP: Extract StreamRefs (In/Out)
BP->>BP: Extract ModuleRefs (Spec/Module)
BP->>MC: build() - deploy modules
MC->>Calc: Instantiate Calculator
MC->>Client: Instantiate Client
Note over BP,MC: Connection Phase
BP->>BP: _connect_module_refs()
BP->>BP: Find module matching ComputeSpec
BP->>BP: Check spec_structural_compliance(Calculator, ComputeSpec)
BP->>BP: Check spec_annotation_compliance(Calculator, ComputeSpec)
BP->>Client: setattr(calc, calculator_instance)
BP->>Client: set_module_ref("calc", calculator_instance)
BP->>BP: _connect_rpc_methods()
BP->>RPC: Register Calculator.compute1
BP->>RPC: Register Calculator.compute2
BP->>Client: set_rpc_method("Calculator.compute1", callable)
BP->>Client: set_rpc_method("Calculator.compute2", callable)
Note over Client,RPC: Runtime RPC Call
Client->>Client: start()
Client->>Calc: self.calc.compute1(2, 3)
Calc->>RPC: call_sync("Calculator/compute1", args)
RPC->>Calc: Execute compute1(2, 3)
Calc-->>RPC: Return result: 5
RPC-->>Client: Return result: 5
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2 files reviewed, 2 comments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
4 files reviewed, 1 comment
| ) | ||
|
|
||
| # if the spec is actually module, use that (basically a user override) | ||
| if inspect.isclass(spec, type) and issubclass(spec, Module): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
inspect.isclass() only takes one argument, not two
| if inspect.isclass(spec, type) and issubclass(spec, Module): | |
| if inspect.isclass(spec) and issubclass(spec, Module): |
| @@ -0,0 +1,56 @@ | |||
| # Copyright 2026 Dimensional Inc. | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this example be in the docs? I don't think anyone will look at it here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I should have updated blueprints.md for the docs and the had this as a standalone example for people who jump into the code. (I believe this dir is linked to somewhere in the docs)
| def _connect_transports(self, module_coordinator: ModuleCoordinator) -> None: | ||
| # Gather all the In/Out connections with remapping applied. | ||
| # dict when given (final/remapped) connection name+type, provides a list of modules + original (non-remapped) connection names | ||
| connections = defaultdict(list) | ||
| # Track original name -> remapped name for each module | ||
| module_conn_mapping = defaultdict(dict) # type: ignore[var-annotated] | ||
|
|
||
| for blueprint in self.blueprints: | ||
| for conn in blueprint.connections: | ||
| # Check if this connection should be remapped | ||
| remapped_name = self.remapping_map.get((blueprint.module, conn.name), conn.name) | ||
| # Store the mapping for later use | ||
| module_conn_mapping[blueprint.module][conn.name] = remapped_name | ||
| # Group by remapped name and type | ||
| connections[remapped_name, conn.type].append((blueprint.module, conn.name)) | ||
| if isinstance(remapped_name, str): | ||
| # Group by remapped name and type | ||
| connections[remapped_name, conn.type].append((blueprint.module, conn.name)) | ||
|
|
||
| # Connect all In/Out connections by remapped name and type. | ||
| for remapped_name, type in connections.keys(): | ||
| transport = self._get_transport_for(remapped_name, type) | ||
| for module, original_name in connections[(remapped_name, type)]: | ||
| instance = module_coordinator.get_instance(module) | ||
| for remapped_name, stream_type in connections.keys(): | ||
| transport = self._get_transport_for(remapped_name, stream_type) | ||
| for module, original_name in connections[(remapped_name, stream_type)]: | ||
| instance = module_coordinator.get_instance(module) # type: ignore[assignment] | ||
| instance.set_transport(original_name, transport) # type: ignore[union-attr] | ||
| logger.info( | ||
| "Transport", | ||
| name=remapped_name, | ||
| original_name=original_name, | ||
| topic=str(getattr(transport, "topic", None)), | ||
| type=f"{type.__module__}.{type.__qualname__}", | ||
| type=f"{stream_type.__module__}.{stream_type.__qualname__}", | ||
| module=module.__name__, | ||
| transport=transport.__class__.__name__, | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this should be called _connect_streams() and connection renamed to stream everywhere in this func to match the rest of the renames.
I'll fix the test in just a bit