mirror of
https://github.com/Astatin3/unshell.git
synced 2026-06-08 22:38:01 -06:00
Add crossbeam channel router leaf example
This commit is contained in:
@@ -276,8 +276,7 @@ fn generated_call_procedure_can_query_and_mutate_endpoint_topology() {
|
||||
.send_call(
|
||||
path(&["agent"]),
|
||||
Some(TopologyLeaf::protocol_leaf_name()),
|
||||
TopologyLeaf::protocol_procedure_id("remove_child")
|
||||
.expect("suffix should resolve"),
|
||||
TopologyLeaf::protocol_procedure_id("remove_child").expect("suffix should resolve"),
|
||||
Some(remove_hook),
|
||||
encode_call_reply(&ChildRequest {
|
||||
child_path: path(&["agent", "child"]),
|
||||
|
||||
@@ -9,11 +9,11 @@ use crate::protocol::{
|
||||
CallMessage, DataMessage, FrameBytes, FrameError, HookTarget, PacketHeader, ProtocolFault,
|
||||
};
|
||||
|
||||
use super::endpoint::ForwardedFrame;
|
||||
use super::{
|
||||
Endpoint, EndpointError, HookKey, Ingress, LocalEvent, ProtocolEndpoint, ProtocolLeaf,
|
||||
RouteDecision, RouterLeaf,
|
||||
};
|
||||
use super::endpoint::ForwardedFrame;
|
||||
|
||||
/// One typed incoming `Call` passed to a leaf procedure.
|
||||
///
|
||||
@@ -665,9 +665,10 @@ where
|
||||
packet.data,
|
||||
packet.end_hook,
|
||||
)?;
|
||||
runtime
|
||||
.forwarded
|
||||
.extend(self.process_endpoint_outcome_routed(endpoint_outcome)?.forwarded);
|
||||
runtime.forwarded.extend(
|
||||
self.process_endpoint_outcome_routed(endpoint_outcome)?
|
||||
.forwarded,
|
||||
);
|
||||
}
|
||||
Ok(runtime)
|
||||
}
|
||||
|
||||
@@ -281,7 +281,11 @@ impl ProtocolEndpoint {
|
||||
/// ```
|
||||
pub fn upsert_child_route(&mut self, route: ChildRoute) -> Result<(), EndpointError> {
|
||||
self.validate_direct_child_path(&route.path)?;
|
||||
if let Some(existing) = self.children.iter_mut().find(|child| child.path == route.path) {
|
||||
if let Some(existing) = self
|
||||
.children
|
||||
.iter_mut()
|
||||
.find(|child| child.path == route.path)
|
||||
{
|
||||
*existing = route;
|
||||
} else {
|
||||
self.children.push(route);
|
||||
@@ -371,23 +375,27 @@ impl ProtocolEndpoint {
|
||||
|
||||
fn validate_direct_parent_path(&self, parent_path: &[String]) -> Result<(), EndpointError> {
|
||||
let Some((_, expected_parent)) = self.path.split_last() else {
|
||||
return Err(EndpointError::Validation(ValidationError::TopologyInvariant(
|
||||
"root endpoints cannot declare a parent path",
|
||||
)));
|
||||
return Err(EndpointError::Validation(
|
||||
ValidationError::TopologyInvariant("root endpoints cannot declare a parent path"),
|
||||
));
|
||||
};
|
||||
if parent_path != expected_parent {
|
||||
return Err(EndpointError::Validation(ValidationError::TopologyInvariant(
|
||||
"parent path must equal the direct path prefix of this endpoint",
|
||||
)));
|
||||
return Err(EndpointError::Validation(
|
||||
ValidationError::TopologyInvariant(
|
||||
"parent path must equal the direct path prefix of this endpoint",
|
||||
),
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate_direct_child_path(&self, child_path: &[String]) -> Result<(), EndpointError> {
|
||||
if child_path.len() != self.path.len() + 1 || !child_path.starts_with(&self.path) {
|
||||
return Err(EndpointError::Validation(ValidationError::TopologyInvariant(
|
||||
"child path must be one direct descendant of this endpoint",
|
||||
)));
|
||||
return Err(EndpointError::Validation(
|
||||
ValidationError::TopologyInvariant(
|
||||
"child path must be one direct descendant of this endpoint",
|
||||
),
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -11,6 +11,6 @@ mod introspection;
|
||||
mod receive;
|
||||
|
||||
pub use core::{
|
||||
ChildRoute, Endpoint, EndpointError, EndpointOutcome, ForwardedFrame, Ingress, LeafSpec, LocalEvent,
|
||||
ProtocolEndpoint,
|
||||
ChildRoute, Endpoint, EndpointError, EndpointOutcome, ForwardedFrame, Ingress, LeafSpec,
|
||||
LocalEvent, ProtocolEndpoint,
|
||||
};
|
||||
|
||||
@@ -190,13 +190,13 @@ pub trait CallProcedures: LeafDeclaration {
|
||||
/// use unshell::protocol::tree::{CallProcedures, DispatchError, IncomingCall, ProtocolLeaf};
|
||||
/// struct ExampleLeaf;
|
||||
/// impl ProtocolLeaf for ExampleLeaf { fn leaf_name() -> String { "org.example.v1.echo".into() } }
|
||||
/// impl CallProcedures for ExampleLeaf {
|
||||
/// type Error = core::convert::Infallible;
|
||||
/// fn procedure_suffixes() -> &'static [&'static str] { &["invoke"] }
|
||||
/// fn dispatch_call(&mut self, _endpoint: &mut unshell::protocol::tree::ProtocolEndpoint, _call: IncomingCall) -> Result<unshell::protocol::tree::CallReply, DispatchError<Self::Error>> {
|
||||
/// Ok(unshell::protocol::tree::CallReply::NoReply)
|
||||
/// }
|
||||
/// }
|
||||
/// impl CallProcedures for ExampleLeaf {
|
||||
/// type Error = core::convert::Infallible;
|
||||
/// fn procedure_suffixes() -> &'static [&'static str] { &["invoke"] }
|
||||
/// fn dispatch_call(&mut self, _endpoint: &mut unshell::protocol::tree::ProtocolEndpoint, _call: IncomingCall) -> Result<unshell::protocol::tree::CallReply, DispatchError<Self::Error>> {
|
||||
/// Ok(unshell::protocol::tree::CallReply::NoReply)
|
||||
/// }
|
||||
/// }
|
||||
/// # let _ = ExampleLeaf;
|
||||
/// ```
|
||||
fn dispatch_call(
|
||||
|
||||
Reference in New Issue
Block a user