mirror of
https://github.com/Astatin3/unshell.git
synced 2026-06-08 22:38:01 -06:00
Simplify endpoint outcome state handling
This commit is contained in:
@@ -111,7 +111,7 @@ impl ProtocolEndpoint {
|
||||
) -> Self {
|
||||
let registered_child_paths = children
|
||||
.iter()
|
||||
.filter(|child| child.state == super::core::ConnectionState::Registered)
|
||||
.filter(|child| child.registered)
|
||||
.map(|child| child.path.clone())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
@@ -180,12 +180,12 @@ impl ProtocolEndpoint {
|
||||
self.hooks
|
||||
.remove_pending(&HookKey::new(hook.return_path.clone(), hook.hook_id));
|
||||
}
|
||||
Ok(EndpointOutcome::dropped())
|
||||
Ok(EndpointOutcome::Dropped)
|
||||
}
|
||||
route => Ok(EndpointOutcome::forward(
|
||||
route => Ok(EndpointOutcome::Forward {
|
||||
route,
|
||||
encode_packet(&header, &call)?,
|
||||
)),
|
||||
frame: encode_packet(&header, &call)?,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,11 +246,11 @@ impl ProtocolEndpoint {
|
||||
|
||||
match self.decide_route(&header.dst_path) {
|
||||
RouteDecision::Local => self.handle_local_data(header, message),
|
||||
RouteDecision::Drop => Ok(EndpointOutcome::dropped()),
|
||||
route => Ok(EndpointOutcome::forward(
|
||||
RouteDecision::Drop => Ok(EndpointOutcome::Dropped),
|
||||
route => Ok(EndpointOutcome::Forward {
|
||||
route,
|
||||
encode_packet(&header, &message)?,
|
||||
)),
|
||||
frame: encode_packet(&header, &message)?,
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,20 +13,13 @@ use crate::protocol::{
|
||||
|
||||
use super::super::{CompiledRoutes, HookKey, HookTable, RouteDecision};
|
||||
|
||||
/// Registration state for a direct child endpoint.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum ConnectionState {
|
||||
Unregistered,
|
||||
Registered,
|
||||
}
|
||||
|
||||
/// Routing metadata for one direct child endpoint.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct ChildRoute {
|
||||
/// Absolute path for the child endpoint inside the protocol tree.
|
||||
pub path: Vec<String>,
|
||||
/// Whether this child currently participates in routing decisions.
|
||||
pub state: ConnectionState,
|
||||
pub registered: bool,
|
||||
}
|
||||
|
||||
impl ChildRoute {
|
||||
@@ -34,7 +27,7 @@ impl ChildRoute {
|
||||
pub fn registered(path: Vec<String>) -> Self {
|
||||
Self {
|
||||
path,
|
||||
state: ConnectionState::Registered,
|
||||
registered: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -76,43 +69,14 @@ pub enum LocalEvent {
|
||||
}
|
||||
|
||||
/// Result of processing a frame or building a locally-sent packet.
|
||||
#[derive(Debug, Default)]
|
||||
pub struct EndpointOutcome {
|
||||
#[derive(Debug)]
|
||||
pub enum EndpointOutcome {
|
||||
/// Frame to forward, together with the next routing decision.
|
||||
pub forward: Option<(RouteDecision, FrameBytes)>,
|
||||
Forward { route: RouteDecision, frame: FrameBytes },
|
||||
/// Locally-delivered protocol event.
|
||||
pub event: Option<LocalEvent>,
|
||||
/// Whether the packet was intentionally discarded.
|
||||
pub dropped: bool,
|
||||
}
|
||||
|
||||
impl EndpointOutcome {
|
||||
#[must_use]
|
||||
pub fn forward(route: RouteDecision, frame: FrameBytes) -> Self {
|
||||
Self {
|
||||
forward: Some((route, frame)),
|
||||
event: None,
|
||||
dropped: false,
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn event(event: LocalEvent) -> Self {
|
||||
Self {
|
||||
forward: None,
|
||||
event: Some(event),
|
||||
dropped: false,
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn dropped() -> Self {
|
||||
Self {
|
||||
forward: None,
|
||||
event: None,
|
||||
dropped: true,
|
||||
}
|
||||
}
|
||||
Local(LocalEvent),
|
||||
/// Packet intentionally discarded.
|
||||
Dropped,
|
||||
}
|
||||
|
||||
/// Error surfaced while validating or encoding protocol frames.
|
||||
|
||||
@@ -16,7 +16,7 @@ impl ProtocolEndpoint {
|
||||
fault: ProtocolFault,
|
||||
) -> Result<EndpointOutcome, EndpointError> {
|
||||
let Some(key) = key else {
|
||||
return Ok(EndpointOutcome::dropped());
|
||||
return Ok(EndpointOutcome::Dropped);
|
||||
};
|
||||
|
||||
self.hooks.remove_pending(&key);
|
||||
@@ -32,15 +32,15 @@ impl ProtocolEndpoint {
|
||||
let message = FaultMessage { fault };
|
||||
|
||||
match self.decide_route(&key.return_path) {
|
||||
RouteDecision::Local => Ok(EndpointOutcome::event(LocalEvent::Fault {
|
||||
RouteDecision::Local => Ok(EndpointOutcome::Local(LocalEvent::Fault {
|
||||
header,
|
||||
message,
|
||||
hook_key: key,
|
||||
})),
|
||||
route => Ok(EndpointOutcome::forward(
|
||||
route => Ok(EndpointOutcome::Forward {
|
||||
route,
|
||||
encode_packet(&header, &message)?,
|
||||
)),
|
||||
frame: encode_packet(&header, &message)?,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,12 +64,12 @@ impl ProtocolEndpoint {
|
||||
self.hooks.activate_pending(&pending_key);
|
||||
pending_key
|
||||
} else {
|
||||
return Ok(EndpointOutcome::dropped());
|
||||
return Ok(EndpointOutcome::Dropped);
|
||||
}
|
||||
};
|
||||
|
||||
let Some(active) = self.hooks.active(&key) else {
|
||||
return Ok(EndpointOutcome::dropped());
|
||||
return Ok(EndpointOutcome::Dropped);
|
||||
};
|
||||
|
||||
if active.peer_path != header.src_path {
|
||||
@@ -81,14 +81,14 @@ impl ProtocolEndpoint {
|
||||
|
||||
if active.procedure_id != message.procedure_id {
|
||||
// Data frames stay bound to the procedure chosen by the original call.
|
||||
return Ok(EndpointOutcome::dropped());
|
||||
return Ok(EndpointOutcome::Dropped);
|
||||
}
|
||||
|
||||
if message.end_hook && self.hooks.mark_peer_end(&key) {
|
||||
self.hooks.remove_active(&key);
|
||||
}
|
||||
|
||||
Ok(EndpointOutcome::event(LocalEvent::Data {
|
||||
Ok(EndpointOutcome::Local(LocalEvent::Data {
|
||||
header,
|
||||
message,
|
||||
hook_key: key,
|
||||
@@ -106,7 +106,7 @@ impl ProtocolEndpoint {
|
||||
.resolve_active_key(&self.path, hook_id, &header.src_path)
|
||||
{
|
||||
self.hooks.remove_active(&key);
|
||||
return Ok(EndpointOutcome::event(LocalEvent::Fault {
|
||||
return Ok(EndpointOutcome::Local(LocalEvent::Fault {
|
||||
header,
|
||||
message,
|
||||
hook_key: key,
|
||||
@@ -120,14 +120,14 @@ impl ProtocolEndpoint {
|
||||
.is_some_and(|pending| pending.caller_src_path == header.src_path)
|
||||
{
|
||||
self.hooks.remove_pending(&pending_key);
|
||||
return Ok(EndpointOutcome::event(LocalEvent::Fault {
|
||||
return Ok(EndpointOutcome::Local(LocalEvent::Fault {
|
||||
header,
|
||||
message,
|
||||
hook_key: pending_key,
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(EndpointOutcome::dropped())
|
||||
Ok(EndpointOutcome::Dropped)
|
||||
}
|
||||
|
||||
pub(crate) fn decide_route(&self, dst_path: &[String]) -> RouteDecision {
|
||||
|
||||
@@ -18,7 +18,7 @@ impl ProtocolEndpoint {
|
||||
key: Option<HookKey>,
|
||||
) -> Result<EndpointOutcome, EndpointError> {
|
||||
let Some(key) = key else {
|
||||
return Ok(EndpointOutcome::dropped());
|
||||
return Ok(EndpointOutcome::Dropped);
|
||||
};
|
||||
|
||||
let response_payload = if let Some(leaf_name) = &header.dst_leaf {
|
||||
@@ -36,7 +36,7 @@ impl ProtocolEndpoint {
|
||||
sub_endpoints: self
|
||||
.children
|
||||
.iter()
|
||||
.filter(|child| child.state == super::core::ConnectionState::Registered)
|
||||
.filter(|child| child.registered)
|
||||
.filter_map(|child| child.path.get(self.path.len()).cloned())
|
||||
.collect(),
|
||||
leaves: self
|
||||
@@ -72,16 +72,16 @@ impl ProtocolEndpoint {
|
||||
|
||||
match self.decide_route(&key.return_path) {
|
||||
super::super::RouteDecision::Local => {
|
||||
Ok(EndpointOutcome::event(super::core::LocalEvent::Data {
|
||||
Ok(EndpointOutcome::Local(super::core::LocalEvent::Data {
|
||||
header: response_header,
|
||||
message: response,
|
||||
hook_key: key,
|
||||
}))
|
||||
}
|
||||
route => Ok(EndpointOutcome::forward(
|
||||
route => Ok(EndpointOutcome::Forward {
|
||||
route,
|
||||
encode_packet(&response_header, &response)?,
|
||||
)),
|
||||
frame: encode_packet(&response_header, &response)?,
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,6 @@ mod introspection;
|
||||
mod receive;
|
||||
|
||||
pub use core::{
|
||||
ChildRoute, ConnectionState, Endpoint, EndpointError, EndpointOutcome, Ingress, LeafSpec,
|
||||
LocalEvent, ProtocolEndpoint,
|
||||
ChildRoute, Endpoint, EndpointError, EndpointOutcome, Ingress, LeafSpec, LocalEvent,
|
||||
ProtocolEndpoint,
|
||||
};
|
||||
|
||||
@@ -75,7 +75,7 @@ impl ProtocolEndpoint {
|
||||
return self.emit_fault_if_possible(key, ProtocolFault::INTERNAL_ERROR);
|
||||
}
|
||||
|
||||
Ok(EndpointOutcome::event(LocalEvent::Call { header, message }))
|
||||
Ok(EndpointOutcome::Local(LocalEvent::Call { header, message }))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ impl Endpoint for ProtocolEndpoint {
|
||||
validate_header(header)?;
|
||||
|
||||
if !self.valid_source_for_ingress(ingress, &header.src_path) {
|
||||
return Ok(EndpointOutcome::dropped());
|
||||
return Ok(EndpointOutcome::Dropped);
|
||||
}
|
||||
|
||||
match header.packet_type {
|
||||
@@ -103,17 +103,19 @@ impl Endpoint for ProtocolEndpoint {
|
||||
// itself. Children can return data/faults, but they do not initiate new
|
||||
// calls through this node.
|
||||
if !matches!(ingress, Ingress::Parent | Ingress::Local) {
|
||||
return Ok(EndpointOutcome::dropped());
|
||||
return Ok(EndpointOutcome::Dropped);
|
||||
}
|
||||
|
||||
match self.decide_route(&header.dst_path) {
|
||||
RouteDecision::Child(index) => {
|
||||
Ok(EndpointOutcome::forward(RouteDecision::Child(index), frame))
|
||||
}
|
||||
RouteDecision::Parent => {
|
||||
Ok(EndpointOutcome::forward(RouteDecision::Parent, frame))
|
||||
}
|
||||
RouteDecision::Drop => Ok(EndpointOutcome::dropped()),
|
||||
RouteDecision::Child(index) => Ok(EndpointOutcome::Forward {
|
||||
route: RouteDecision::Child(index),
|
||||
frame,
|
||||
}),
|
||||
RouteDecision::Parent => Ok(EndpointOutcome::Forward {
|
||||
route: RouteDecision::Parent,
|
||||
frame,
|
||||
}),
|
||||
RouteDecision::Drop => Ok(EndpointOutcome::Dropped),
|
||||
RouteDecision::Local => {
|
||||
let (header, payload) = parsed.into_parts();
|
||||
let message = deserialize_archived_bytes::<ArchivedCallMessage, CallMessage>(
|
||||
@@ -133,11 +135,15 @@ impl Endpoint for ProtocolEndpoint {
|
||||
>(payload)?;
|
||||
self.handle_local_data(header, message)
|
||||
}
|
||||
RouteDecision::Child(index) => {
|
||||
Ok(EndpointOutcome::forward(RouteDecision::Child(index), frame))
|
||||
}
|
||||
RouteDecision::Parent => Ok(EndpointOutcome::forward(RouteDecision::Parent, frame)),
|
||||
RouteDecision::Drop => Ok(EndpointOutcome::dropped()),
|
||||
RouteDecision::Child(index) => Ok(EndpointOutcome::Forward {
|
||||
route: RouteDecision::Child(index),
|
||||
frame,
|
||||
}),
|
||||
RouteDecision::Parent => Ok(EndpointOutcome::Forward {
|
||||
route: RouteDecision::Parent,
|
||||
frame,
|
||||
}),
|
||||
RouteDecision::Drop => Ok(EndpointOutcome::Dropped),
|
||||
},
|
||||
PacketType::Fault => match self.decide_route(&header.dst_path) {
|
||||
RouteDecision::Local => {
|
||||
@@ -148,11 +154,15 @@ impl Endpoint for ProtocolEndpoint {
|
||||
>(payload)?;
|
||||
self.handle_local_fault(header, message)
|
||||
}
|
||||
RouteDecision::Child(index) => {
|
||||
Ok(EndpointOutcome::forward(RouteDecision::Child(index), frame))
|
||||
}
|
||||
RouteDecision::Parent => Ok(EndpointOutcome::forward(RouteDecision::Parent, frame)),
|
||||
RouteDecision::Drop => Ok(EndpointOutcome::dropped()),
|
||||
RouteDecision::Child(index) => Ok(EndpointOutcome::Forward {
|
||||
route: RouteDecision::Child(index),
|
||||
frame,
|
||||
}),
|
||||
RouteDecision::Parent => Ok(EndpointOutcome::Forward {
|
||||
route: RouteDecision::Parent,
|
||||
frame,
|
||||
}),
|
||||
RouteDecision::Drop => Ok(EndpointOutcome::Dropped),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user