diff --git a/commons/zenoh-protocol/src/network/declare.rs b/commons/zenoh-protocol/src/network/declare.rs index 6efd69d31f..7f9e7a11a9 100644 --- a/commons/zenoh-protocol/src/network/declare.rs +++ b/commons/zenoh-protocol/src/network/declare.rs @@ -148,6 +148,21 @@ impl Declare { body, } } + + #[inline] + pub fn wire_expr(&self) -> Option<&WireExpr> { + match &self.body { + DeclareBody::DeclareKeyExpr(m) => Some(&m.wire_expr), + DeclareBody::UndeclareKeyExpr(_) => None, + DeclareBody::DeclareSubscriber(m) => Some(&m.wire_expr), + DeclareBody::UndeclareSubscriber(m) => Some(&m.ext_wire_expr.wire_expr), + DeclareBody::DeclareQueryable(m) => Some(&m.wire_expr), + DeclareBody::UndeclareQueryable(m) => Some(&m.ext_wire_expr.wire_expr), + DeclareBody::DeclareToken(m) => Some(&m.wire_expr), + DeclareBody::UndeclareToken(m) => Some(&m.ext_wire_expr.wire_expr), + DeclareBody::DeclareFinal(_) => None, + } + } } pub mod common { diff --git a/zenoh/src/net/primitives/demux.rs b/zenoh/src/net/primitives/demux.rs index 1f10646410..f918f99bc4 100644 --- a/zenoh/src/net/primitives/demux.rs +++ b/zenoh/src/net/primitives/demux.rs @@ -11,104 +11,30 @@ // Contributors: // ZettaScale Zenoh Team, // -use std::{any::Any, sync::Arc}; +use std::any::Any; -use arc_swap::ArcSwap; use zenoh_link::Link; -use zenoh_protocol::network::{ - ext, response, Declare, DeclareBody, DeclareFinal, NetworkBodyMut, NetworkMessageMut, - ResponseFinal, -}; +use zenoh_protocol::network::{NetworkBodyMut, NetworkMessageMut}; use zenoh_result::ZResult; use zenoh_transport::{unicast::TransportUnicast, TransportPeerEventHandler}; use super::Primitives; -use crate::net::routing::{ - dispatcher::face::Face, - interceptor::{InterceptorTrait, InterceptorsChain}, - RoutingContext, -}; +use crate::net::routing::dispatcher::face::Face; pub struct DeMux { face: Face, pub(crate) transport: Option, - pub(crate) interceptor: Arc>, } impl DeMux { - pub(crate) fn new( - face: Face, - transport: Option, - interceptor: Arc>, - ) -> Self { - Self { - face, - transport, - interceptor, - } + pub(crate) fn new(face: Face, transport: Option) -> Self { + Self { face, transport } } } impl TransportPeerEventHandler for DeMux { #[inline] - fn handle_message(&self, mut msg: NetworkMessageMut) -> ZResult<()> { - let interceptor = self.interceptor.load(); - if !interceptor.interceptors.is_empty() { - let mut ctx = RoutingContext::new_in(msg.as_mut(), self.face.clone()); - let prefix = ctx - .wire_expr() - .and_then(|we| (!we.has_suffix()).then(|| ctx.prefix())) - .flatten() - .cloned(); - let cache_guard = prefix - .as_ref() - .and_then(|p| p.get_ingress_cache(&self.face, &interceptor)); - let cache = cache_guard.as_ref().and_then(|c| c.get_ref().as_ref()); - - match &ctx.msg.body { - NetworkBodyMut::Request(request) => { - let request_id = request.id; - if !interceptor.intercept(&mut ctx, cache) { - // request was blocked by an interceptor, we need to send response final to avoid timeout error - self.face - .state - .primitives - .send_response_final(&mut ResponseFinal { - rid: request_id, - ext_qos: response::ext::QoSType::RESPONSE_FINAL, - ext_tstamp: None, - }); - return Ok(()); - } - } - NetworkBodyMut::Interest(interest) => { - let interest_id = interest.id; - if !interceptor.intercept(&mut ctx, cache) { - // request was blocked by an interceptor, we need to send declare final to avoid timeout error - self.face - .state - .primitives - .send_declare(RoutingContext::new_in( - &mut Declare { - interest_id: Some(interest_id), - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareFinal(DeclareFinal), - }, - self.face.clone(), - )); - return Ok(()); - } - } - _ => { - if !interceptor.intercept(&mut ctx, cache) { - return Ok(()); - } - } - }; - } - + fn handle_message(&self, msg: NetworkMessageMut) -> ZResult<()> { match msg.body { NetworkBodyMut::Push(m) => self.face.send_push(m, msg.reliability), NetworkBodyMut::Declare(m) => self.face.send_declare(m), @@ -126,12 +52,12 @@ impl TransportPeerEventHandler for DeMux { &self.face.tables, m, transport, - &mut |p, m| declares.push((p.clone(), m)), + &mut |p, m, r| declares.push((p.clone(), m, r)), )?; drop(tables); drop(ctrl_lock); - for (p, m) in declares { - m.with_mut(|m| p.send_declare(m)); + for (p, mut m, r) in declares { + p.intercept_declare(&mut m, r.as_ref()); } } } diff --git a/zenoh/src/net/primitives/mux.rs b/zenoh/src/net/primitives/mux.rs index 7b1b0998fc..2ec3603cae 100644 --- a/zenoh/src/net/primitives/mux.rs +++ b/zenoh/src/net/primitives/mux.rs @@ -11,101 +11,44 @@ // Contributors: // ZettaScale Zenoh Team, // -use std::sync::OnceLock; -use arc_swap::ArcSwap; use zenoh_protocol::{ core::Reliability, network::{ - interest::Interest, response, Declare, NetworkBodyMut, NetworkMessageMut, Push, Request, - Response, ResponseFinal, + interest::Interest, Declare, NetworkBodyMut, NetworkMessageMut, Push, Request, Response, + ResponseFinal, }, }; use zenoh_transport::{multicast::TransportMulticast, unicast::TransportUnicast}; -use super::{EPrimitives, Primitives}; -use crate::net::routing::{ - dispatcher::face::{Face, WeakFace}, - interceptor::{InterceptorTrait, InterceptorsChain}, - RoutingContext, -}; +use super::EPrimitives; +use crate::net::routing::RoutingContext; pub struct Mux { pub handler: TransportUnicast, - pub(crate) face: OnceLock, - pub(crate) interceptor: ArcSwap, } impl Mux { - pub(crate) fn new(handler: TransportUnicast, interceptor: InterceptorsChain) -> Mux { - Mux { - handler, - face: OnceLock::new(), - interceptor: ArcSwap::new(interceptor.into()), - } + pub(crate) fn new(handler: TransportUnicast) -> Mux { + Mux { handler } } } impl EPrimitives for Mux { fn send_interest(&self, ctx: RoutingContext<&mut Interest>) { - let interest_id = ctx.msg.id; - let mut ctx = RoutingContext { - msg: NetworkMessageMut { - body: NetworkBodyMut::Interest(ctx.msg), - reliability: Reliability::Reliable, - }, - inface: ctx.inface, - outface: ctx.outface, - prefix: ctx.prefix, - full_expr: ctx.full_expr, + let msg = NetworkMessageMut { + body: NetworkBodyMut::Interest(ctx.msg), + reliability: Reliability::Reliable, }; - let prefix = ctx - .wire_expr() - .and_then(|we| (!we.has_suffix()).then(|| ctx.prefix())) - .flatten() - .cloned(); - let interceptor = self.interceptor.load(); - let cache_guard = prefix - .as_ref() - .and_then(|p| p.get_egress_cache(ctx.outface.get().unwrap(), &interceptor)); - - let cache = cache_guard.as_ref().and_then(|c| c.get_ref().as_ref()); - - if self.interceptor.load().intercept(&mut ctx, cache) { - let _ = self.handler.schedule(ctx.msg); - } else { - // send declare final to avoid timeout on blocked interest - if let Some(face) = self.face.get().and_then(|f| f.upgrade()) { - face.reject_interest(interest_id); - } - } + let _ = self.handler.schedule(msg); } fn send_declare(&self, ctx: RoutingContext<&mut Declare>) { - let mut ctx = RoutingContext { - msg: NetworkMessageMut { - body: NetworkBodyMut::Declare(ctx.msg), - reliability: Reliability::Reliable, - }, - inface: ctx.inface, - outface: ctx.outface, - prefix: ctx.prefix, - full_expr: ctx.full_expr, + let msg = NetworkMessageMut { + body: NetworkBodyMut::Declare(ctx.msg), + reliability: Reliability::Reliable, }; - let prefix = ctx - .wire_expr() - .and_then(|we| (!we.has_suffix()).then(|| ctx.prefix())) - .flatten() - .cloned(); - let interceptor = self.interceptor.load(); - let cache_guard = prefix - .as_ref() - .and_then(|p| p.get_egress_cache(ctx.outface.get().unwrap(), &interceptor)); - let cache = cache_guard.as_ref().and_then(|c| c.get_ref().as_ref()); - - if self.interceptor.load().intercept(&mut ctx, cache) { - let _ = self.handler.schedule(ctx.msg); - } + let _ = self.handler.schedule(msg); } fn send_push(&self, msg: &mut Push, reliability: Reliability) { @@ -113,63 +56,17 @@ impl EPrimitives for Mux { body: NetworkBodyMut::Push(msg), reliability, }; - let interceptor = self.interceptor.load(); - if interceptor.interceptors.is_empty() { - let _ = self.handler.schedule(msg); - } else if let Some(face) = self.face.get().and_then(|f| f.upgrade()) { - let mut ctx = RoutingContext::new_out(msg, face.clone()); - let prefix = ctx - .wire_expr() - .and_then(|we| (!we.has_suffix()).then(|| ctx.prefix())) - .flatten() - .cloned(); - let cache_guard = prefix - .as_ref() - .and_then(|p| p.get_egress_cache(&face, &interceptor)); - let cache = cache_guard.as_ref().and_then(|c| c.get_ref().as_ref()); - if interceptor.intercept(&mut ctx, cache) { - let _ = self.handler.schedule(ctx.msg); - } - } else { - tracing::error!("Uninitialized multiplexer!"); - } + let _ = self.handler.schedule(msg); } fn send_request(&self, msg: &mut Request) { - let request_id = msg.id; let msg = NetworkMessageMut { body: NetworkBodyMut::Request(msg), reliability: Reliability::Reliable, }; - let interceptor = self.interceptor.load(); - if interceptor.interceptors.is_empty() { - let _ = self.handler.schedule(msg); - } else if let Some(face) = self.face.get().and_then(|f| f.upgrade()) { - let mut ctx = RoutingContext::new_out(msg, face.clone()); - let prefix = ctx - .wire_expr() - .and_then(|we| (!we.has_suffix()).then(|| ctx.prefix())) - .flatten() - .cloned(); - let cache_guard = prefix - .as_ref() - .and_then(|p| p.get_egress_cache(&face, &interceptor)); - let cache = cache_guard.as_ref().and_then(|c| c.get_ref().as_ref()); - if interceptor.intercept(&mut ctx, cache) { - let _ = self.handler.schedule(ctx.msg); - } else { - // request was blocked by an interceptor, we need to send response final to avoid timeout error - face.send_response_final(&mut ResponseFinal { - rid: request_id, - ext_qos: response::ext::QoSType::RESPONSE_FINAL, - ext_tstamp: None, - }) - } - } else { - tracing::error!("Uninitialized multiplexer!"); - } + let _ = self.handler.schedule(msg); } fn send_response(&self, msg: &mut Response) { @@ -177,27 +74,7 @@ impl EPrimitives for Mux { body: NetworkBodyMut::Response(msg), reliability: Reliability::Reliable, }; - let interceptor = self.interceptor.load(); - if interceptor.interceptors.is_empty() { - let _ = self.handler.schedule(msg); - } else if let Some(face) = self.face.get().and_then(|f| f.upgrade()) { - let mut ctx = RoutingContext::new_out(msg, face.clone()); - let prefix = ctx - .wire_expr() - .and_then(|we| (!we.has_suffix()).then(|| ctx.prefix())) - .flatten() - .cloned(); - let cache_guard = prefix - .as_ref() - .and_then(|p| p.get_egress_cache(&face, &interceptor)); - let cache = cache_guard.as_ref().and_then(|c| c.get_ref().as_ref()); - - if interceptor.intercept(&mut ctx, cache) { - let _ = self.handler.schedule(ctx.msg); - } - } else { - tracing::error!("Uninitialized multiplexer!"); - } + let _ = self.handler.schedule(msg); } fn send_response_final(&self, msg: &mut ResponseFinal) { @@ -205,26 +82,7 @@ impl EPrimitives for Mux { body: NetworkBodyMut::ResponseFinal(msg), reliability: Reliability::Reliable, }; - let interceptor = self.interceptor.load(); - if interceptor.interceptors.is_empty() { - let _ = self.handler.schedule(msg); - } else if let Some(face) = self.face.get().and_then(|f| f.upgrade()) { - let mut ctx = RoutingContext::new_out(msg, face.clone()); - let prefix = ctx - .wire_expr() - .and_then(|we| (!we.has_suffix()).then(|| ctx.prefix())) - .flatten() - .cloned(); - let cache_guard = prefix - .as_ref() - .and_then(|p| p.get_egress_cache(&face, &interceptor)); - let cache = cache_guard.as_ref().and_then(|c| c.get_ref().as_ref()); - if interceptor.intercept(&mut ctx, cache) { - let _ = self.handler.schedule(ctx.msg); - } - } else { - tracing::error!("Uninitialized multiplexer!"); - } + let _ = self.handler.schedule(msg); } fn as_any(&self) -> &dyn std::any::Any { @@ -234,71 +92,29 @@ impl EPrimitives for Mux { pub struct McastMux { pub handler: TransportMulticast, - pub(crate) face: OnceLock, - pub(crate) interceptor: ArcSwap, } impl McastMux { - pub(crate) fn new(handler: TransportMulticast, interceptor: InterceptorsChain) -> McastMux { - McastMux { - handler, - face: OnceLock::new(), - interceptor: ArcSwap::new(interceptor.into()), - } + pub(crate) fn new(handler: TransportMulticast) -> McastMux { + McastMux { handler } } } impl EPrimitives for McastMux { fn send_interest(&self, ctx: RoutingContext<&mut Interest>) { - let mut ctx = RoutingContext { - msg: NetworkMessageMut { - body: NetworkBodyMut::Interest(ctx.msg), - reliability: Reliability::Reliable, - }, - inface: ctx.inface, - outface: ctx.outface, - prefix: ctx.prefix, - full_expr: ctx.full_expr, + let msg = NetworkMessageMut { + body: NetworkBodyMut::Interest(ctx.msg), + reliability: Reliability::Reliable, }; - let prefix = ctx - .wire_expr() - .and_then(|we| (!we.has_suffix()).then(|| ctx.prefix())) - .flatten() - .cloned(); - let interceptor = self.interceptor.load(); - let cache_guard = prefix - .as_ref() - .and_then(|p| p.get_egress_cache(ctx.outface.get().unwrap(), &interceptor)); - let cache = cache_guard.as_ref().and_then(|c| c.get_ref().as_ref()); - if self.interceptor.load().intercept(&mut ctx, cache) { - let _ = self.handler.schedule(ctx.msg); - } + let _ = self.handler.schedule(msg); } fn send_declare(&self, ctx: RoutingContext<&mut Declare>) { - let mut ctx = RoutingContext { - msg: NetworkMessageMut { - body: NetworkBodyMut::Declare(ctx.msg), - reliability: Reliability::Reliable, - }, - inface: ctx.inface, - outface: ctx.outface, - prefix: ctx.prefix, - full_expr: ctx.full_expr, + let msg = NetworkMessageMut { + body: NetworkBodyMut::Declare(ctx.msg), + reliability: Reliability::Reliable, }; - let prefix = ctx - .wire_expr() - .and_then(|we| (!we.has_suffix()).then(|| ctx.prefix())) - .flatten() - .cloned(); - let interceptor = self.interceptor.load(); - let cache_guard = prefix - .as_ref() - .and_then(|p| p.get_egress_cache(ctx.outface.get().unwrap(), &interceptor)); - let cache = cache_guard.as_ref().and_then(|c| c.get_ref().as_ref()); - if self.interceptor.load().intercept(&mut ctx, cache) { - let _ = self.handler.schedule(ctx.msg); - } + let _ = self.handler.schedule(msg); } fn send_push(&self, msg: &mut Push, reliability: Reliability) { @@ -306,26 +122,7 @@ impl EPrimitives for McastMux { body: NetworkBodyMut::Push(msg), reliability, }; - let interceptor = self.interceptor.load(); - if interceptor.interceptors.is_empty() { - let _ = self.handler.schedule(msg); - } else if let Some(face) = self.face.get() { - let mut ctx = RoutingContext::new_out(msg, face.clone()); - let prefix = ctx - .wire_expr() - .and_then(|we| (!we.has_suffix()).then(|| ctx.prefix())) - .flatten() - .cloned(); - let cache_guard = prefix - .as_ref() - .and_then(|p| p.get_egress_cache(face, &interceptor)); - let cache = cache_guard.as_ref().and_then(|c| c.get_ref().as_ref()); - if interceptor.intercept(&mut ctx, cache) { - let _ = self.handler.schedule(ctx.msg); - } - } else { - tracing::error!("Uninitialized multiplexer!"); - } + let _ = self.handler.schedule(msg); } fn send_request(&self, msg: &mut Request) { @@ -333,26 +130,7 @@ impl EPrimitives for McastMux { body: NetworkBodyMut::Request(msg), reliability: Reliability::Reliable, }; - let interceptor = self.interceptor.load(); - if interceptor.interceptors.is_empty() { - let _ = self.handler.schedule(msg); - } else if let Some(face) = self.face.get() { - let mut ctx = RoutingContext::new_out(msg, face.clone()); - let prefix = ctx - .wire_expr() - .and_then(|we| (!we.has_suffix()).then(|| ctx.prefix())) - .flatten() - .cloned(); - let cache_guard = prefix - .as_ref() - .and_then(|p| p.get_egress_cache(face, &interceptor)); - let cache = cache_guard.as_ref().and_then(|c| c.get_ref().as_ref()); - if interceptor.intercept(&mut ctx, cache) { - let _ = self.handler.schedule(ctx.msg); - } - } else { - tracing::error!("Uninitialized multiplexer!"); - } + let _ = self.handler.schedule(msg); } fn send_response(&self, msg: &mut Response) { @@ -360,26 +138,7 @@ impl EPrimitives for McastMux { body: NetworkBodyMut::Response(msg), reliability: Reliability::Reliable, }; - let interceptor = self.interceptor.load(); - if interceptor.interceptors.is_empty() { - let _ = self.handler.schedule(msg); - } else if let Some(face) = self.face.get() { - let mut ctx = RoutingContext::new_out(msg, face.clone()); - let prefix = ctx - .wire_expr() - .and_then(|we| (!we.has_suffix()).then(|| ctx.prefix())) - .flatten() - .cloned(); - let cache_guard = prefix - .as_ref() - .and_then(|p| p.get_egress_cache(face, &interceptor)); - let cache = cache_guard.as_ref().and_then(|c| c.get_ref().as_ref()); - if interceptor.intercept(&mut ctx, cache) { - let _ = self.handler.schedule(ctx.msg); - } - } else { - tracing::error!("Uninitialized multiplexer!"); - } + let _ = self.handler.schedule(msg); } fn send_response_final(&self, msg: &mut ResponseFinal) { @@ -387,26 +146,7 @@ impl EPrimitives for McastMux { body: NetworkBodyMut::ResponseFinal(msg), reliability: Reliability::Reliable, }; - let interceptor = self.interceptor.load(); - if interceptor.interceptors.is_empty() { - let _ = self.handler.schedule(msg); - } else if let Some(face) = self.face.get() { - let mut ctx = RoutingContext::new_out(msg, face.clone()); - let prefix = ctx - .wire_expr() - .and_then(|we| (!we.has_suffix()).then(|| ctx.prefix())) - .flatten() - .cloned(); - let cache_guard = prefix - .as_ref() - .and_then(|p| p.get_egress_cache(face, &interceptor)); - let cache = cache_guard.as_ref().and_then(|c| c.get_ref().as_ref()); - if interceptor.intercept(&mut ctx, cache) { - let _ = self.handler.schedule(ctx.msg); - } - } else { - tracing::error!("Uninitialized multiplexer!"); - } + let _ = self.handler.schedule(msg); } fn as_any(&self) -> &dyn std::any::Any { diff --git a/zenoh/src/net/routing/dispatcher/face.rs b/zenoh/src/net/routing/dispatcher/face.rs index d26502eb62..ed96aac00f 100644 --- a/zenoh/src/net/routing/dispatcher/face.rs +++ b/zenoh/src/net/routing/dispatcher/face.rs @@ -15,19 +15,22 @@ use std::{ any::Any, collections::HashMap, fmt, - ops::Not, - sync::{Arc, Weak}, + ops::{Deref, Not}, + sync::{Arc, RwLockReadGuard, Weak}, time::Duration, }; use ahash::HashMapExt; use arc_swap::ArcSwap; use tokio_util::sync::CancellationToken; +use zenoh_config::InterceptorFlow; use zenoh_protocol::{ - core::{ExprId, Reliability, WhatAmI, ZenohIdProto}, + core::{ExprId, Reliability, WhatAmI, WireExpr, ZenohIdProto}, network::{ + declare, interest::{InterestId, InterestMode, InterestOptions}, - Mapping, Push, Request, RequestId, Response, ResponseFinal, + response, Declare, DeclareBody, DeclareFinal, Interest, Mapping, NetworkBodyMut, + NetworkMessageMut, Push, Request, RequestId, Response, ResponseFinal, }, zenoh::RequestBody, }; @@ -41,16 +44,17 @@ use super::{ super::router::*, interests::{declare_final, declare_interest, undeclare_interest, PendingCurrentInterest}, resource::*, - tables::TablesLock, + tables::{Tables, TablesLock}, }; use crate::net::{ - primitives::{McastMux, Mux, Primitives}, + primitives::{EPrimitives, McastMux, Mux, Primitives}, routing::{ dispatcher::interests::finalize_pending_interests, interceptor::{ EgressInterceptor, IngressInterceptor, InterceptorFactory, InterceptorTrait, InterceptorsChain, }, + RoutingContext, }, }; @@ -75,7 +79,8 @@ pub struct FaceState { pub(crate) next_qid: RequestId, pub(crate) pending_queries: HashMap, CancellationToken)>, pub(crate) mcast_group: Option, - pub(crate) in_interceptors: Option>>, + pub(crate) in_interceptors: Option>, + pub(crate) eg_interceptors: Option>, pub(crate) hat: Box, pub(crate) task_controller: TaskController, pub(crate) is_local: bool, @@ -90,7 +95,8 @@ impl FaceState { #[cfg(feature = "stats")] stats: Option>, primitives: Arc, mcast_group: Option, - in_interceptors: Option>>, + in_interceptors: Option>, + eg_interceptors: Option>, hat: Box, is_local: bool, ) -> Arc { @@ -110,6 +116,7 @@ impl FaceState { pending_queries: HashMap::new(), mcast_group, in_interceptors, + eg_interceptors, hat, task_controller: TaskController::default(), is_local, @@ -119,24 +126,24 @@ impl FaceState { #[inline] pub(crate) fn get_mapping( &self, - prefixid: &ExprId, + prefixid: ExprId, mapping: Mapping, ) -> Option<&std::sync::Arc> { match mapping { - Mapping::Sender => self.remote_mappings.get(prefixid), - Mapping::Receiver => self.local_mappings.get(prefixid), + Mapping::Sender => self.remote_mappings.get(&prefixid), + Mapping::Receiver => self.local_mappings.get(&prefixid), } } #[inline] pub(crate) fn get_sent_mapping( &self, - prefixid: &ExprId, + prefixid: ExprId, mapping: Mapping, ) -> Option<&std::sync::Arc> { match mapping { - Mapping::Sender => self.local_mappings.get(prefixid), - Mapping::Receiver => self.remote_mappings.get(prefixid), + Mapping::Sender => self.local_mappings.get(&prefixid), + Mapping::Receiver => self.remote_mappings.get(&prefixid), } } @@ -148,60 +155,65 @@ impl FaceState { id } - pub(crate) fn update_interceptors_caches(&self, res: &mut Arc) { - if let Some(interceptor) = self - .in_interceptors - .as_ref() - .map(|itor| itor.load()) - .and_then(|is| is.is_empty().not().then_some(is)) - { - if let Some(expr) = res.keyexpr() { - let cache = interceptor.compute_keyexpr_cache(expr); - get_mut_unchecked( - get_mut_unchecked(res) - .session_ctxs - .get_mut(&self.id) - .unwrap(), - ) - .in_interceptor_cache = InterceptorCache::new(cache, interceptor.version); - } + pub(crate) fn load_interceptors( + &self, + flow: InterceptorFlow, + ) -> Option>> { + match flow { + InterceptorFlow::Egress => &self.eg_interceptors, + InterceptorFlow::Ingress => &self.in_interceptors, } + .as_ref() + .map(|iceptors| iceptors.load()) + .and_then(|iceptors| iceptors.is_empty().not().then_some(iceptors)) + } - if let Some(interceptor) = self - .primitives - .as_any() - .downcast_ref::() - .map(|mux| mux.interceptor.load()) - .and_then(|is| is.is_empty().not().then_some(is)) - { + pub(crate) fn exec_interceptors( + &self, + flow: InterceptorFlow, + iceptor: &InterceptorsChain, + ctx: &mut RoutingContext>, + ) -> bool { + // NOTE: the cache should be empty if the wire expr has a suffix, i.e. when the prefix + // doesn't represent a full keyexpr. + let prefix = ctx.wire_expr().and_then(|we| { + if we.has_suffix() { + None + } else { + ctx.prefix.get() + } + }); + let cache_guard = prefix + .as_ref() + .and_then(|p| p.interceptor_cache(self, iceptor, flow)); + let cache = cache_guard.as_ref().and_then(|c| c.get_ref().as_ref()); + iceptor.intercept(ctx, cache) + } + + pub(crate) fn update_interceptors_caches(&self, res: &mut Arc) { + if let Some(iceptor) = self.load_interceptors(InterceptorFlow::Ingress) { if let Some(expr) = res.keyexpr() { - let cache = interceptor.compute_keyexpr_cache(expr); + let cache = iceptor.compute_keyexpr_cache(expr); get_mut_unchecked( get_mut_unchecked(res) .session_ctxs .get_mut(&self.id) .unwrap(), ) - .e_interceptor_cache = InterceptorCache::new(cache, interceptor.version); + .in_interceptor_cache = InterceptorCache::new(cache, iceptor.version); } } - if let Some(interceptor) = self - .primitives - .as_any() - .downcast_ref::() - .map(|mux| mux.interceptor.load()) - .and_then(|is| is.is_empty().not().then_some(is)) - { + if let Some(iceptor) = self.load_interceptors(InterceptorFlow::Egress) { if let Some(expr) = res.keyexpr() { - let cache = interceptor.compute_keyexpr_cache(expr); + let cache = iceptor.compute_keyexpr_cache(expr); get_mut_unchecked( get_mut_unchecked(res) .session_ctxs .get_mut(&self.id) .unwrap(), ) - .e_interceptor_cache = InterceptorCache::new(cache, interceptor.version); + .e_interceptor_cache = InterceptorCache::new(cache, iceptor.version); } } } @@ -220,11 +232,14 @@ impl FaceState { InterceptorsChain::new(ingress.into_iter().flatten().collect::>(), version), InterceptorsChain::new(egress.into_iter().flatten().collect::>(), version), ); - mux.interceptor.store(egress.into()); self.in_interceptors .as_ref() .expect("face in_interceptors should not be None when primitives are Mux") - .store(ingress.into()); + .store(Arc::new(ingress)); + self.eg_interceptors + .as_ref() + .expect("face eg_interceptors should not be None when primitives are Mux") + .store(Arc::new(egress)); } else if let Some(mux) = self.primitives.as_any().downcast_ref::() { let interceptor = InterceptorsChain::new( factories @@ -233,7 +248,10 @@ impl FaceState { .collect::>(), version, ); - mux.interceptor.store(Arc::new(interceptor)); + self.eg_interceptors + .as_ref() + .expect("face eg_interceptors should not be None when primitives are DeMux") + .store(Arc::new(interceptor)); debug_assert!(self.in_interceptors.is_none()); } else if let Some(transport) = &self.mcast_group { let interceptor = InterceptorsChain::new( @@ -249,6 +267,12 @@ impl FaceState { .store(interceptor.into()); } } + + pub(crate) fn reject_interest(&self, interest_id: u32) { + if let Some(interest) = self.pending_current_interests.get(&interest_id) { + interest.rejection_token.cancel(); + } + } } impl fmt::Display for FaceState { @@ -286,31 +310,82 @@ impl Face { } } - pub(crate) fn reject_interest(&self, interest_id: u32) { - if let Some(interest) = self.state.pending_current_interests.get(&interest_id) { - interest.rejection_token.cancel(); - } + /// Returns a reference to the **ingress** primitives of this [`Face`]. + /// + /// Use the returned [`Primitives`] to send messages that loop back + /// into this same side of the [`Face`]. + pub(crate) fn ingress_primitives(&self) -> &dyn Primitives { + self + } + + /// Returns a reference to the **egress** primitives of this [`Face`]. + /// + /// Use the returned [`EPrimitives`] to send messages outward from + /// this side to the other side of the [`Face`]. + pub(crate) fn egress_primitives(&self) -> &dyn EPrimitives { + &*self.state.primitives } } impl Primitives for Face { fn send_interest(&self, msg: &mut zenoh_protocol::network::Interest) { + if let Some(iceptor) = self.state.load_interceptors(InterceptorFlow::Ingress) { + let Ok(prefix) = msg + .wire_expr + .as_ref() + .map(|we| self.ingress_prefix(we)) + .transpose() + else { + return; + }; + + let interest_id = msg.id; + let msg = NetworkMessageMut { + body: NetworkBodyMut::Interest(msg), + reliability: Reliability::Reliable, // Interest is always reliable + }; + let ctx = &mut match &prefix { + Some(prefix) => RoutingContext::with_prefix(msg, prefix.prefix.clone()), + None => RoutingContext::new(msg), + }; + + if !self + .state + .exec_interceptors(InterceptorFlow::Ingress, &iceptor, ctx) + { + // NOTE: this request was blocked by an ingress interceptor, we need to send + // DeclareFinal to avoid a timeout error. + self.egress_primitives() + .send_declare(RoutingContext::with_expr( + &mut Declare { + interest_id: Some(interest_id), + ext_qos: declare::ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: declare::ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareFinal(DeclareFinal), + }, + prefix.map(|res| res.expr().to_string()).unwrap_or_default(), + )); + return; + } + } + let ctrl_lock = zlock!(self.tables.ctrl_lock); if msg.mode != InterestMode::Final { let mut declares = vec![]; declare_interest( ctrl_lock.as_ref(), &self.tables, - &mut self.state.clone(), + self, msg.id, msg.wire_expr.as_ref(), msg.mode, msg.options, - &mut |p, m| declares.push((p.clone(), m)), + &mut |p, m, r| declares.push((p.clone(), m, r)), ); drop(ctrl_lock); - for (p, m) in declares { - m.with_mut(|m| p.send_declare(m)); + for (p, mut m, r) in declares { + p.intercept_declare(&mut m, r.as_ref()); } } else { undeclare_interest( @@ -323,10 +398,37 @@ impl Primitives for Face { } fn send_declare(&self, msg: &mut zenoh_protocol::network::Declare) { + if let Some(iceptor) = self.state.load_interceptors(InterceptorFlow::Ingress) { + let Ok(prefix) = msg + .wire_expr() + .map(|we| self.ingress_prefix(we)) + .transpose() + else { + return; + }; + + let msg = NetworkMessageMut { + body: NetworkBodyMut::Declare(msg), + reliability: Reliability::Reliable, // Declare is always reliable + }; + + let ctx = &mut match prefix { + Some(prefix) => RoutingContext::with_prefix(msg, prefix.clone()), + None => RoutingContext::new(msg), + }; + + if !self + .state + .exec_interceptors(InterceptorFlow::Ingress, &iceptor, ctx) + { + return; + } + } + let ctrl_lock = zlock!(self.tables.ctrl_lock); match &mut msg.body { zenoh_protocol::network::DeclareBody::DeclareKeyExpr(m) => { - register_expr(&self.tables, &mut self.state.clone(), m.id, &m.wire_expr); + register_expr(&self.tables, self, m.id, &m.wire_expr); } zenoh_protocol::network::DeclareBody::UndeclareKeyExpr(m) => { unregister_expr(&self.tables, &mut self.state.clone(), m.id); @@ -336,16 +438,16 @@ impl Primitives for Face { declare_subscription( ctrl_lock.as_ref(), &self.tables, - &mut self.state.clone(), + self, m.id, &m.wire_expr, &SubscriberInfo, msg.ext_nodeid.node_id, - &mut |p, m| declares.push((p.clone(), m)), + &mut |p, m, r| declares.push((p.clone(), m, r)), ); drop(ctrl_lock); - for (p, m) in declares { - m.with_mut(|m| p.send_declare(m)); + for (p, mut m, r) in declares { + p.intercept_declare(&mut m, r.as_ref()); } } zenoh_protocol::network::DeclareBody::UndeclareSubscriber(m) => { @@ -357,11 +459,11 @@ impl Primitives for Face { m.id, &m.ext_wire_expr.wire_expr, msg.ext_nodeid.node_id, - &mut |p, m| declares.push((p.clone(), m)), + &mut |p, m, r| declares.push((p.clone(), m, r)), ); drop(ctrl_lock); - for (p, m) in declares { - m.with_mut(|m| p.send_declare(m)); + for (p, mut m, r) in declares { + p.intercept_declare(&mut m, r.as_ref()) } } zenoh_protocol::network::DeclareBody::DeclareQueryable(m) => { @@ -369,16 +471,16 @@ impl Primitives for Face { declare_queryable( ctrl_lock.as_ref(), &self.tables, - &mut self.state.clone(), + self, m.id, &m.wire_expr, &m.ext_info, msg.ext_nodeid.node_id, - &mut |p, m| declares.push((p.clone(), m)), + &mut |p, m, r| declares.push((p.clone(), m, r)), ); drop(ctrl_lock); - for (p, m) in declares { - m.with_mut(|m| p.send_declare(m)); + for (p, mut m, r) in declares { + p.intercept_declare(&mut m, r.as_ref()) } } zenoh_protocol::network::DeclareBody::UndeclareQueryable(m) => { @@ -390,11 +492,11 @@ impl Primitives for Face { m.id, &m.ext_wire_expr.wire_expr, msg.ext_nodeid.node_id, - &mut |p, m| declares.push((p.clone(), m)), + &mut |p, m, r| declares.push((p.clone(), m, r)), ); drop(ctrl_lock); - for (p, m) in declares { - m.with_mut(|m| p.send_declare(m)); + for (p, mut m, r) in declares { + p.intercept_declare(&mut m, r.as_ref()) } } zenoh_protocol::network::DeclareBody::DeclareToken(m) => { @@ -402,16 +504,16 @@ impl Primitives for Face { declare_token( ctrl_lock.as_ref(), &self.tables, - &mut self.state.clone(), + self, m.id, &m.wire_expr, msg.ext_nodeid.node_id, msg.interest_id, - &mut |p, m| declares.push((p.clone(), m)), + &mut |p, m, r| declares.push((p.clone(), m, r)), ); drop(ctrl_lock); - for (p, m) in declares { - m.with_mut(|m| p.send_declare(m)); + for (p, mut m, r) in declares { + p.intercept_declare(&mut m, r.as_ref()) } } zenoh_protocol::network::DeclareBody::UndeclareToken(m) => { @@ -423,11 +525,11 @@ impl Primitives for Face { m.id, &m.ext_wire_expr, msg.ext_nodeid.node_id, - &mut |p, m| declares.push((p.clone(), m)), + &mut |p, m, r| declares.push((p.clone(), m, r)), ); drop(ctrl_lock); - for (p, m) in declares { - m.with_mut(|m| p.send_declare(m)); + for (p, mut m, r) in declares { + p.intercept_declare(&mut m, r.as_ref()) } } zenoh_protocol::network::DeclareBody::DeclareFinal(_) => { @@ -444,15 +546,15 @@ impl Primitives for Face { &mut wtables, &mut self.state.clone(), id, - &mut |p, m| declares.push((p.clone(), m)), + &mut |p, m, r| declares.push((p.clone(), m, r)), ); wtables.disable_all_routes(); drop(wtables); drop(ctrl_lock); - for (p, m) in declares { - m.with_mut(|m| p.send_declare(m)); + for (p, mut m, r) in declares { + p.intercept_declare(&mut m, r.as_ref()) } } } @@ -461,22 +563,108 @@ impl Primitives for Face { #[inline] fn send_push(&self, msg: &mut Push, reliability: Reliability) { + if let Some(iceptor) = self.state.load_interceptors(InterceptorFlow::Ingress) { + let Ok(prefix) = self.ingress_prefix(&msg.wire_expr) else { + return; + }; + + let ctx = &mut RoutingContext::with_prefix( + NetworkMessageMut { + body: NetworkBodyMut::Push(msg), + reliability, + }, + prefix.prefix, + ); + + if !self + .state + .exec_interceptors(InterceptorFlow::Ingress, &iceptor, ctx) + { + return; + } + } + route_data(&self.tables, &self.state, msg, reliability); } fn send_request(&self, msg: &mut Request) { + if let Some(iceptor) = self.state.load_interceptors(InterceptorFlow::Ingress) { + let Ok(prefix) = self.ingress_prefix(&msg.wire_expr) else { + return; + }; + + let ctx = &mut RoutingContext::with_prefix( + NetworkMessageMut { + body: NetworkBodyMut::Request(msg), + reliability: Reliability::Reliable, // NOTE: queries are always reliable + }, + prefix.prefix, + ); + + if !self + .state + .exec_interceptors(InterceptorFlow::Ingress, &iceptor, ctx) + { + // NOTE: this request was blocked by an ingress interceptor, we need to send + // ResponseFinal to avoid a timeout error. + self.egress_primitives() + .send_response_final(&mut ResponseFinal { + rid: msg.id, + ext_qos: response::ext::QoSType::RESPONSE_FINAL, + ext_tstamp: None, + }); + return; + } + } + match msg.payload { RequestBody::Query(_) => { - route_query(&self.tables, &self.state, msg); + route_query(&self.tables, self, msg); } } } fn send_response(&self, msg: &mut Response) { + if let Some(iceptor) = self.state.load_interceptors(InterceptorFlow::Ingress) { + let Ok(prefix) = self.ingress_prefix(&msg.wire_expr) else { + return; + }; + + let ctx = &mut RoutingContext::with_prefix( + NetworkMessageMut { + body: NetworkBodyMut::Response(msg), + reliability: Reliability::Reliable, // NOTE: queries are always reliable + }, + prefix.prefix, + ); + + if !self + .state + .exec_interceptors(InterceptorFlow::Ingress, &iceptor, ctx) + { + return; + } + } + route_send_response(&self.tables, &mut self.state.clone(), msg); } fn send_response_final(&self, msg: &mut ResponseFinal) { + if let Some(iceptor) = self.state.load_interceptors(InterceptorFlow::Ingress) { + let ctx = &mut RoutingContext::new(NetworkMessageMut { + body: NetworkBodyMut::ResponseFinal(msg), + reliability: Reliability::Reliable, // NOTE: queries are always reliable + }); + + // NOTE: ResponseFinal messages have no keyexpr + if !self + .state + .exec_interceptors(InterceptorFlow::Ingress, &iceptor, ctx) + { + return; + } + } + route_send_response_final(&self.tables, &mut self.state.clone(), msg.rid); } @@ -487,18 +675,18 @@ impl Primitives for Face { finalize_pending_queries(&self.tables, &mut state); let mut declares = vec![]; let ctrl_lock = zlock!(self.tables.ctrl_lock); - finalize_pending_interests(&self.tables, &mut state, &mut |p, m| { - declares.push((p.clone(), m)) + finalize_pending_interests(&self.tables, &mut state, &mut |p, m, r| { + declares.push((p.clone(), m, r)) }); ctrl_lock.close_face( &self.tables, &self.tables.clone(), &mut state, - &mut |p, m| declares.push((p.clone(), m)), + &mut |p, m, r| declares.push((p.clone(), m, r)), ); drop(ctrl_lock); - for (p, m) in declares { - m.with_mut(|m| p.send_declare(m)); + for (p, mut m, r) in declares { + p.intercept_declare(&mut m, r.as_ref()) } } @@ -512,3 +700,238 @@ impl fmt::Display for Face { self.state.fmt(f) } } + +/// [`Resource`] prefix. +/// +/// # Safety +/// +/// The [`Tables`] lock is also stored to ensure that the [`Resource`] is not accessed without it. +/// Otherwise we could run into undefined behavior when using [`get_mut_unchecked`]. +pub(crate) struct Prefix<'face> { + _tables: RwLockReadGuard<'face, Tables>, + pub prefix: Arc, +} + +impl Deref for Prefix<'_> { + type Target = Arc; + + fn deref(&self) -> &Self::Target { + &self.prefix + } +} + +impl Face { + /// Returns the [`Prefix`] associated with the given [`WireExpr`] for transmitted messages. + pub(crate) fn egress_prefix(&self, wire_expr: &WireExpr) -> Result, ()> { + let tables = self + .tables + .tables + .read() + .expect("reading Tables should not fail"); + + match tables + .get_sent_mapping(&self.state, wire_expr.scope, wire_expr.mapping) + .cloned() + { + Some(prefix) => Ok(Prefix { + _tables: tables, + prefix, + }), + None => { + tracing::error!( + "Got WireExpr with unknown scope {} from {}", + wire_expr.scope, + self + ); + Err(()) + } + } + } + + /// Returns the [`Prefix`] associated with the given [`WireExpr`] for received messages. + pub(crate) fn ingress_prefix(&self, wire_expr: &WireExpr) -> Result, ()> { + let tables = self + .tables + .tables + .read() + .expect("reading Tables should not fail"); + + match tables + .get_mapping(&self.state, wire_expr.scope, wire_expr.mapping) + .cloned() + { + Some(prefix) => Ok(Prefix { + _tables: tables, + prefix, + }), + None => { + tracing::error!( + "Got WireExpr with unknown scope {} from {}", + wire_expr.scope, + self + ); + Err(()) + } + } + } + + pub(crate) fn intercept_interest(&self, msg: &mut Interest, prefix: Option<&Arc>) { + if let Some(iceptor) = self.state.load_interceptors(InterceptorFlow::Egress) { + let interest_id = msg.id; + let msg = NetworkMessageMut { + body: NetworkBodyMut::Interest(msg), + reliability: Reliability::Reliable, // NOTE: Interest is always reliable + }; + + let ctx = &mut match prefix { + Some(prefix) => RoutingContext::with_prefix(msg, prefix.clone()), + None => RoutingContext::new(msg), + }; + + if !self + .state + .exec_interceptors(InterceptorFlow::Egress, &iceptor, ctx) + { + // NOTE: this request was blocked by an egress interceptor, we need to send + // DeclareFinal to avoid a timeout error. + self.state.reject_interest(interest_id); + return; + } + } + + self.egress_primitives() + .send_interest(RoutingContext::with_expr( + msg, + prefix.map(|res| res.expr().to_string()).unwrap_or_default(), + )); + } + + pub(crate) fn intercept_declare(&self, msg: &mut Declare, prefix: Option<&Arc>) { + if let Some(iceptor) = self.state.load_interceptors(InterceptorFlow::Egress) { + let msg = NetworkMessageMut { + body: NetworkBodyMut::Declare(msg), + reliability: Reliability::Reliable, // NOTE: Declare is always reliable + }; + + let ctx = &mut match prefix { + Some(prefix) => RoutingContext::with_prefix(msg, prefix.clone()), + None => RoutingContext::new(msg), + }; + + if !self + .state + .exec_interceptors(InterceptorFlow::Egress, &iceptor, ctx) + { + return; + } + } + + self.egress_primitives() + .send_declare(RoutingContext::with_expr( + msg, + prefix.map(|res| res.expr().to_string()).unwrap_or_default(), + )); + } + + pub(crate) fn intercept_push(&self, msg: &mut Push, reliability: Reliability) { + if let Some(iceptor) = self.state.load_interceptors(InterceptorFlow::Egress) { + let Ok(prefix) = self.egress_prefix(&msg.wire_expr) else { + return; + }; + + let ctx = &mut RoutingContext::with_prefix( + NetworkMessageMut { + body: NetworkBodyMut::Push(msg), + reliability, + }, + prefix.prefix, + ); + + if !self + .state + .exec_interceptors(InterceptorFlow::Egress, &iceptor, ctx) + { + return; + } + } + + self.egress_primitives().send_push(msg, reliability); + } + + pub(crate) fn intercept_request(&self, msg: &mut Request) { + if let Some(iceptor) = self.state.load_interceptors(InterceptorFlow::Egress) { + let Ok(prefix) = self.egress_prefix(&msg.wire_expr) else { + return; + }; + + let ctx = &mut RoutingContext::with_prefix( + NetworkMessageMut { + body: NetworkBodyMut::Request(msg), + reliability: Reliability::Reliable, // NOTE: Request is always reliable + }, + prefix.prefix, + ); + + if !self + .state + .exec_interceptors(InterceptorFlow::Egress, &iceptor, ctx) + { + // NOTE: this request was blocked by an egress interceptor, we need to send + // ResponseFinal to avoid timeout error. + self.ingress_primitives() + .send_response_final(&mut ResponseFinal { + rid: msg.id, + ext_qos: response::ext::QoSType::RESPONSE_FINAL, + ext_tstamp: None, + }); + return; + } + } + + self.egress_primitives().send_request(msg); + } + + pub(crate) fn intercept_response(&self, msg: &mut Response) { + if let Some(iceptor) = self.state.load_interceptors(InterceptorFlow::Egress) { + let Ok(prefix) = self.egress_prefix(&msg.wire_expr) else { + return; + }; + + let ctx = &mut RoutingContext::with_prefix( + NetworkMessageMut { + body: NetworkBodyMut::Response(msg), + reliability: Reliability::Reliable, // NOTE: Response is always reliable + }, + prefix.prefix, + ); + + if !self + .state + .exec_interceptors(InterceptorFlow::Egress, &iceptor, ctx) + { + return; + } + } + + self.egress_primitives().send_response(msg); + } + + pub(crate) fn intercept_response_final(&self, msg: &mut ResponseFinal) { + if let Some(iceptor) = self.state.load_interceptors(InterceptorFlow::Egress) { + let ctx = &mut RoutingContext::new(NetworkMessageMut { + body: NetworkBodyMut::ResponseFinal(msg), + reliability: Reliability::Reliable, // NOTE: ResponseFinal is always reliable + }); + + // NOTE: ResponseFinal messages have no keyexpr + if !self + .state + .exec_interceptors(InterceptorFlow::Egress, &iceptor, ctx) + { + return; + } + } + + self.egress_primitives().send_response_final(msg); + } +} diff --git a/zenoh/src/net/routing/dispatcher/interests.rs b/zenoh/src/net/routing/dispatcher/interests.rs index 9511c1d82a..dc3f35149f 100644 --- a/zenoh/src/net/routing/dispatcher/interests.rs +++ b/zenoh/src/net/routing/dispatcher/interests.rs @@ -33,17 +33,16 @@ use zenoh_sync::get_mut_unchecked; use zenoh_util::Timed; use super::{ - face::FaceState, + face::{Face, FaceState}, tables::{register_expr_interest, Tables, TablesLock}, }; use crate::net::routing::{ hat::{HatTrait, SendDeclare}, router::{unregister_expr_interest, Resource}, - RoutingContext, }; pub(crate) struct CurrentInterest { - pub(crate) src_face: Arc, + pub(crate) src_face: Face, pub(crate) src_interest_id: InterestId, pub(crate) mode: InterestMode, } @@ -116,14 +115,15 @@ pub(crate) fn finalize_pending_interest( interest.src_interest_id ); send_declare( - &interest.src_face.primitives, - RoutingContext::new(Declare { + &interest.src_face, + Declare { interest_id: Some(interest.src_interest_id), ext_qos: ext::QoSType::DECLARE, ext_tstamp: None, ext_nodeid: ext::NodeIdType::DEFAULT, body: DeclareBody::DeclareFinal(DeclareFinal), - }), + }, + None, ); } } @@ -181,7 +181,9 @@ impl CurrentInterestCleanup { self.interests_timeout, ); } - finalize_pending_interest(interest, &mut |p, m| m.with_mut(|m| p.send_declare(m))); + finalize_pending_interest(interest, &mut |p, mut m, r| { + p.intercept_declare(&mut m, r.as_ref()) + }); } } } @@ -198,7 +200,7 @@ impl Timed for CurrentInterestCleanup { pub(crate) fn declare_interest( hat_code: &(dyn HatTrait + Send + Sync), tables_ref: &Arc, - face: &mut Arc, + face: &Face, id: InterestId, expr: Option<&WireExpr>, mode: InterestMode, @@ -206,13 +208,13 @@ pub(crate) fn declare_interest( send_declare: &mut SendDeclare, ) { if options.keyexprs() && mode != InterestMode::Current { - register_expr_interest(tables_ref, face, id, expr); + register_expr_interest(tables_ref, &mut face.state.clone(), id, expr); } if let Some(expr) = expr { let rtables = zread!(tables_ref.tables); match rtables - .get_mapping(face, &expr.scope, expr.mapping) + .get_mapping(&face.state, expr.scope, expr.mapping) .cloned() { Some(mut prefix) => { diff --git a/zenoh/src/net/routing/dispatcher/pubsub.rs b/zenoh/src/net/routing/dispatcher/pubsub.rs index 8d0f1ba660..f009787988 100644 --- a/zenoh/src/net/routing/dispatcher/pubsub.rs +++ b/zenoh/src/net/routing/dispatcher/pubsub.rs @@ -25,7 +25,7 @@ use zenoh_protocol::{ use zenoh_sync::get_mut_unchecked; use super::{ - face::FaceState, + face::{Face, FaceState}, resource::{Direction, Resource}, tables::{NodeId, Route, RoutingExpr, Tables, TablesLock}, }; @@ -43,7 +43,7 @@ pub(crate) struct SubscriberInfo; pub(crate) fn declare_subscription( hat_code: &(dyn HatTrait + Send + Sync), tables: &TablesLock, - face: &mut Arc, + face: &Face, id: SubscriberId, expr: &WireExpr, sub_info: &SubscriberInfo, @@ -52,7 +52,7 @@ pub(crate) fn declare_subscription( ) { let rtables = zread!(tables.tables); match rtables - .get_mapping(face, &expr.scope, expr.mapping) + .get_mapping(&face.state, expr.scope, expr.mapping) .cloned() { Some(mut prefix) => { @@ -119,7 +119,7 @@ pub(crate) fn undeclare_subscription( None } else { let rtables = zread!(tables.tables); - match rtables.get_mapping(face, &expr.scope, expr.mapping) { + match rtables.get_mapping(face, expr.scope, expr.mapping) { Some(prefix) => match Resource::get_resource(prefix, expr.suffix.as_ref()) { Some(res) => Some(res), None => { @@ -287,7 +287,7 @@ pub fn route_data( ) { let tables = zread!(tables_ref.tables); match tables - .get_mapping(face, &msg.wire_expr.scope, msg.wire_expr.mapping) + .get_mapping(face, msg.wire_expr.scope, msg.wire_expr.mapping) .cloned() { Some(prefix) => { @@ -320,26 +320,30 @@ pub fn route_data( let (outface, key_expr, context) = route.values().next().unwrap(); if tables .hat_code - .egress_filter(&tables, face, outface, &mut expr) + .egress_filter(&tables, face, &outface.state, &mut expr) { drop(tables); #[cfg(feature = "stats")] if !admin { - inc_stats!(outface, tx, user, msg.payload); + inc_stats!(outface.state, tx, user, msg.payload); } else { - inc_stats!(outface, tx, admin, msg.payload); + inc_stats!(outface.state, tx, admin, msg.payload); } msg.wire_expr = key_expr.into(); msg.ext_nodeid = ext::NodeIdType { node_id: *context }; - outface.primitives.send_push(msg, reliability) + + outface.intercept_push(msg, reliability); } } else { let route = route .values() - .filter(|(outface, _key_expr, _context)| { - tables - .hat_code - .egress_filter(&tables, face, outface, &mut expr) + .filter(|(outface, _key_expr, _context)| -> bool { + tables.hat_code.egress_filter( + &tables, + face, + &outface.state, + &mut expr, + ) }) .cloned() .collect::>(); @@ -348,21 +352,20 @@ pub fn route_data( for (outface, key_expr, context) in route { #[cfg(feature = "stats")] if !admin { - inc_stats!(outface, tx, user, msg.payload) + inc_stats!(outface.state, tx, user, msg.payload) } else { - inc_stats!(outface, tx, admin, msg.payload) + inc_stats!(outface.state, tx, admin, msg.payload) } - outface.primitives.send_push( - &mut Push { - wire_expr: key_expr, - ext_qos: msg.ext_qos, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType { node_id: context }, - payload: msg.payload.clone(), - }, - reliability, - ) + let msg = &mut Push { + wire_expr: key_expr, + ext_qos: msg.ext_qos, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType { node_id: context }, + payload: msg.payload.clone(), + }; + + outface.intercept_push(msg, reliability) } } } diff --git a/zenoh/src/net/routing/dispatcher/queries.rs b/zenoh/src/net/routing/dispatcher/queries.rs index a0b6f3e354..6869bd883c 100644 --- a/zenoh/src/net/routing/dispatcher/queries.rs +++ b/zenoh/src/net/routing/dispatcher/queries.rs @@ -11,11 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use std::{ - collections::HashMap, - sync::{Arc, Weak}, - time::Duration, -}; +use std::{collections::HashMap, sync::Arc, time::Duration}; use async_trait::async_trait; use tokio_util::sync::CancellationToken; @@ -35,7 +31,7 @@ use zenoh_sync::get_mut_unchecked; use zenoh_util::Timed; use super::{ - face::FaceState, + face::{Face, FaceState, WeakFace}, resource::{QueryRoute, QueryTargetQablSet, Resource}, tables::{NodeId, RoutingExpr, Tables, TablesLock}, }; @@ -47,7 +43,7 @@ use crate::net::routing::{ }; pub(crate) struct Query { - src_face: Arc, + src_face: Face, src_qid: RequestId, } @@ -67,7 +63,7 @@ pub(crate) fn get_matching_queryables( pub(crate) fn declare_queryable( hat_code: &(dyn HatTrait + Send + Sync), tables: &TablesLock, - face: &mut Arc, + face: &Face, id: QueryableId, expr: &WireExpr, qabl_info: &QueryableInfoType, @@ -76,7 +72,7 @@ pub(crate) fn declare_queryable( ) { let rtables = zread!(tables.tables); match rtables - .get_mapping(face, &expr.scope, expr.mapping) + .get_mapping(&face.state, expr.scope, expr.mapping) .cloned() { Some(mut prefix) => { @@ -143,7 +139,7 @@ pub(crate) fn undeclare_queryable( None } else { let rtables = zread!(tables.tables); - match rtables.get_mapping(face, &expr.scope, expr.mapping) { + match rtables.get_mapping(face, expr.scope, expr.mapping) { Some(prefix) => match Resource::get_resource(prefix, expr.suffix.as_ref()) { Some(res) => Some(res), None => { @@ -213,11 +209,11 @@ fn compute_final_route( for qabl in qabls.iter() { if tables .hat_code - .egress_filter(tables, src_face, &qabl.direction.0, expr) + .egress_filter(tables, src_face, &qabl.direction.0.state, expr) { - route.entry(qabl.direction.0.id).or_insert_with(|| { + route.entry(qabl.direction.0.state.id).or_insert_with(|| { let mut direction = qabl.direction.clone(); - let qid = insert_pending_query(&mut direction.0, query.clone()); + let qid = insert_pending_query(&mut direction.0.state, query.clone()); (direction, qid) }); } @@ -228,13 +224,16 @@ fn compute_final_route( let mut route = HashMap::new(); for qabl in qabls.iter() { if qabl.info.map(|info| info.complete).unwrap_or(true) - && tables - .hat_code - .egress_filter(tables, src_face, &qabl.direction.0, expr) + && tables.hat_code.egress_filter( + tables, + src_face, + &qabl.direction.0.state, + expr, + ) { - route.entry(qabl.direction.0.id).or_insert_with(|| { + route.entry(qabl.direction.0.state.id).or_insert_with(|| { let mut direction = qabl.direction.clone(); - let qid = insert_pending_query(&mut direction.0, query.clone()); + let qid = insert_pending_query(&mut direction.0.state, query.clone()); (direction, qid) }); } @@ -243,13 +242,14 @@ fn compute_final_route( } QueryTarget::BestMatching => { if let Some(qabl) = qabls.iter().find(|qabl| { - qabl.direction.0.id != src_face.id && qabl.info.is_some_and(|info| info.complete) + qabl.direction.0.state.id != src_face.id + && qabl.info.is_some_and(|info| info.complete) }) { let mut route = HashMap::new(); let mut direction = qabl.direction.clone(); - let qid = insert_pending_query(&mut direction.0, query); - route.insert(direction.0.id, (direction, qid)); + let qid = insert_pending_query(&mut direction.0.state, query); + route.insert(direction.0.state.id, (direction, qid)); route } else { @@ -262,27 +262,28 @@ fn compute_final_route( #[derive(Clone)] struct QueryCleanup { tables: Arc, - face: Weak, + face: WeakFace, qid: RequestId, timeout: Duration, } impl QueryCleanup { pub fn spawn_query_clean_up_task( - face: &Arc, + face: &Face, tables_ref: &Arc, qid: u32, timeout: Duration, ) { let mut cleanup = QueryCleanup { tables: tables_ref.clone(), - face: Arc::downgrade(face), + face: face.downgrade(), qid, timeout, }; - if let Some((_, cancellation_token)) = face.pending_queries.get(&qid) { + if let Some((_, cancellation_token)) = face.state.pending_queries.get(&qid) { let c_cancellation_token = cancellation_token.clone(); - face.task_controller + face.state + .task_controller .spawn_with_rt(zenoh_runtime::ZRuntime::Net, async move { tokio::select! { _ = tokio::time::sleep(timeout) => { cleanup.run().await } @@ -296,14 +297,15 @@ impl QueryCleanup { #[async_trait] impl Timed for QueryCleanup { async fn run(&mut self) { - if let Some(mut face) = self.face.upgrade() { + if let Some(face) = self.face.upgrade() { let ext_respid = Some(response::ext::ResponderIdType { - zid: face.zid, + zid: face.state.zid, eid: 0, }); + let mut face_state = face.state.clone(); route_send_response( &self.tables, - &mut face, + &mut face_state, &mut Response { rid: self.qid, wire_expr: WireExpr::empty(), @@ -321,7 +323,7 @@ impl Timed for QueryCleanup { }, ); let queries_lock = zwrite!(self.tables.queries_lock); - if let Some(query) = get_mut_unchecked(&mut face) + if let Some(query) = get_mut_unchecked(&mut face_state) .pending_queries .remove(&self.qid) { @@ -448,17 +450,18 @@ macro_rules! inc_res_stats { } #[allow(clippy::too_many_arguments)] -pub fn route_query(tables_ref: &Arc, face: &Arc, msg: &mut Request) { +pub fn route_query(tables_ref: &Arc, face: &Face, msg: &mut Request) { let rtables = zread!(tables_ref.tables); - match rtables.get_mapping(face, &msg.wire_expr.scope, msg.wire_expr.mapping) { + match rtables.get_mapping(&face.state, msg.wire_expr.scope, msg.wire_expr.mapping) { Some(prefix) => { tracing::debug!( - "{}:{} Route query for res {}{}", + "{}:{} Route query for resource {}{}", face, msg.id, prefix.expr(), msg.wire_expr.suffix.as_ref(), ); + let prefix = prefix.clone(); let mut expr = RoutingExpr::new(&prefix, msg.wire_expr.suffix.as_ref()); @@ -466,16 +469,24 @@ pub fn route_query(tables_ref: &Arc, face: &Arc, msg: &mu let admin = expr.full_expr().starts_with("@/"); #[cfg(feature = "stats")] if !admin { - inc_req_stats!(face, rx, user, msg.payload) + inc_req_stats!(face.state, rx, user, msg.payload) } else { - inc_req_stats!(face, rx, admin, msg.payload) + inc_req_stats!(face.state, rx, admin, msg.payload) } - if rtables.hat_code.ingress_filter(&rtables, face, &mut expr) { + if rtables + .hat_code + .ingress_filter(&rtables, &face.state, &mut expr) + { let res = Resource::get_resource(&prefix, expr.suffix); - let route = - get_query_route(&rtables, face, &res, &mut expr, msg.ext_nodeid.node_id); + let route = get_query_route( + &rtables, + &face.state, + &res, + &mut expr, + msg.ext_nodeid.node_id, + ); let query = Arc::new(Query { src_face: face.clone(), @@ -483,8 +494,14 @@ pub fn route_query(tables_ref: &Arc, face: &Arc, msg: &mu }); let queries_lock = zwrite!(tables_ref.queries_lock); - let route = - compute_final_route(&rtables, &route, face, &mut expr, &msg.ext_target, query); + let route = compute_final_route( + &rtables, + &route, + &face.state, + &mut expr, + &msg.ext_target, + query, + ); let timeout = msg.ext_timeout.unwrap_or(rtables.queries_default_timeout); drop(queries_lock); drop(rtables); @@ -495,13 +512,11 @@ pub fn route_query(tables_ref: &Arc, face: &Arc, msg: &mu face, msg.id ); - face.primitives - .clone() - .send_response_final(&mut ResponseFinal { - rid: msg.id, - ext_qos: response::ext::QoSType::RESPONSE_FINAL, - ext_tstamp: None, - }); + face.intercept_response_final(&mut ResponseFinal { + rid: msg.id, + ext_qos: response::ext::QoSType::RESPONSE_FINAL, + ext_tstamp: None, + }); } else { for ((outface, key_expr, context), outqid) in route.values() { QueryCleanup::spawn_query_clean_up_task( @@ -509,9 +524,9 @@ pub fn route_query(tables_ref: &Arc, face: &Arc, msg: &mu ); #[cfg(feature = "stats")] if !admin { - inc_req_stats!(outface, tx, user, msg.payload) + inc_req_stats!(&outface.state, tx, user, msg.payload) } else { - inc_req_stats!(outface, tx, admin, msg.payload) + inc_req_stats!(&outface.state, tx, admin, msg.payload) } tracing::trace!( @@ -521,7 +536,8 @@ pub fn route_query(tables_ref: &Arc, face: &Arc, msg: &mu outface, outqid ); - outface.primitives.send_request(&mut Request { + + let msg = &mut Request { id: *outqid, wire_expr: key_expr.into(), ext_qos: msg.ext_qos, @@ -531,19 +547,19 @@ pub fn route_query(tables_ref: &Arc, face: &Arc, msg: &mu ext_budget: msg.ext_budget, ext_timeout: msg.ext_timeout, payload: msg.payload.clone(), - }); + }; + + outface.intercept_request(msg); } } } else { tracing::debug!("{}:{} Send final reply (not master)", face, msg.id); drop(rtables); - face.primitives - .clone() - .send_response_final(&mut ResponseFinal { - rid: msg.id, - ext_qos: response::ext::QoSType::RESPONSE_FINAL, - ext_tstamp: None, - }); + face.intercept_response_final(&mut ResponseFinal { + rid: msg.id, + ext_qos: response::ext::QoSType::RESPONSE_FINAL, + ext_tstamp: None, + }); } } None => { @@ -554,18 +570,15 @@ pub fn route_query(tables_ref: &Arc, face: &Arc, msg: &mu msg.wire_expr.scope, ); drop(rtables); - face.primitives - .clone() - .send_response_final(&mut ResponseFinal { - rid: msg.id, - ext_qos: response::ext::QoSType::RESPONSE_FINAL, - ext_tstamp: None, - }); + face.intercept_response_final(&mut ResponseFinal { + rid: msg.id, + ext_qos: response::ext::QoSType::RESPONSE_FINAL, + ext_tstamp: None, + }); } } } -#[allow(clippy::too_many_arguments)] pub(crate) fn route_send_response( tables_ref: &Arc, face: &mut Arc, @@ -596,13 +609,14 @@ pub(crate) fn route_send_response( #[cfg(feature = "stats")] if !admin { - inc_res_stats!(query.src_face, tx, user, msg.payload) + inc_res_stats!(query.src_face.state, tx, user, msg.payload) } else { - inc_res_stats!(query.src_face, tx, admin, msg.payload) + inc_res_stats!(query.src_face.state, tx, admin, msg.payload) } msg.rid = query.src_qid; - query.src_face.primitives.send_response(msg); + + query.src_face.intercept_response(msg); } None => tracing::warn!("{}:{} Route reply: Query not found!", face, msg.rid), } @@ -643,14 +657,10 @@ pub(crate) fn finalize_pending_query(query: (Arc, CancellationToken)) { cancellation_token.cancel(); if let Some(query) = Arc::into_inner(query) { tracing::debug!("{}:{} Propagate final reply", query.src_face, query.src_qid); - query - .src_face - .primitives - .clone() - .send_response_final(&mut ResponseFinal { - rid: query.src_qid, - ext_qos: response::ext::QoSType::RESPONSE_FINAL, - ext_tstamp: None, - }); + query.src_face.intercept_response_final(&mut ResponseFinal { + rid: query.src_qid, + ext_qos: response::ext::QoSType::RESPONSE_FINAL, + ext_tstamp: None, + }); } } diff --git a/zenoh/src/net/routing/dispatcher/resource.rs b/zenoh/src/net/routing/dispatcher/resource.rs index be47af8d2d..244ed05cef 100644 --- a/zenoh/src/net/routing/dispatcher/resource.rs +++ b/zenoh/src/net/routing/dispatcher/resource.rs @@ -23,7 +23,7 @@ use std::{ use ahash::HashMapExt; use zenoh_collections::SingleOrBoxHashSet; -use zenoh_config::WhatAmI; +use zenoh_config::{InterceptorFlow, WhatAmI}; use zenoh_protocol::{ core::{key_expr::keyexpr, ExprId, WireExpr}, network::{ @@ -35,20 +35,18 @@ use zenoh_protocol::{ use zenoh_sync::{get_mut_unchecked, Cache, CacheValueType}; use super::{ - face::FaceState, + face::{Face, FaceState}, pubsub::SubscriberInfo, tables::{Tables, TablesLock}, }; use crate::net::routing::{ - dispatcher::face::Face, interceptor::{InterceptorTrait, InterceptorsChain}, router::{disable_matches_data_routes, disable_matches_query_routes}, - RoutingContext, }; pub(crate) type NodeId = u16; -pub(crate) type Direction = (Arc, WireExpr<'static>, NodeId); +pub(crate) type Direction = (Face, WireExpr<'static>, NodeId); pub(crate) type Route = HashMap; pub(crate) type QueryRoute = HashMap; @@ -87,7 +85,7 @@ impl InterceptorCache { } pub(crate) struct SessionContext { - pub(crate) face: Arc, + pub(crate) face: Face, pub(crate) local_expr_id: Option, pub(crate) remote_expr_id: Option, pub(crate) subs: Option, @@ -98,7 +96,7 @@ pub(crate) struct SessionContext { } impl SessionContext { - pub(crate) fn new(face: Arc) -> Self { + pub(crate) fn new(face: Face) -> Self { Self { face, local_expr_id: None, @@ -494,12 +492,8 @@ impl Resource { } #[inline] - pub fn decl_key( - res: &Arc, - face: &mut Arc, - push: bool, - ) -> WireExpr<'static> { - if face.is_local { + pub fn decl_key(res: &Arc, face: &Face, push: bool) -> WireExpr<'static> { + if face.state.is_local { return res.expr().to_string().into(); } @@ -508,7 +502,7 @@ impl Resource { Some(mut nonwild_prefix) => { if let Some(ctx) = get_mut_unchecked(&mut nonwild_prefix) .session_ctxs - .get(&face.id) + .get(&face.state.id) { if let Some(expr_id) = ctx.remote_expr_id { return WireExpr { @@ -526,7 +520,7 @@ impl Resource { } } if push - || face.remote_key_interests.values().any(|res| { + || face.state.remote_key_interests.values().any(|res| { res.as_ref() .map(|res| res.matches(&nonwild_prefix)) .unwrap_or(true) @@ -534,14 +528,14 @@ impl Resource { { let ctx = get_mut_unchecked(&mut nonwild_prefix) .session_ctxs - .entry(face.id) + .entry(face.state.id) .or_insert_with(|| Arc::new(SessionContext::new(face.clone()))); - let expr_id = face.get_next_local_id(); + let expr_id = face.state.get_next_local_id(); get_mut_unchecked(ctx).local_expr_id = Some(expr_id); - get_mut_unchecked(face) + get_mut_unchecked(&mut face.state.clone()) .local_mappings .insert(expr_id, nonwild_prefix.clone()); - face.primitives.send_declare(RoutingContext::with_expr( + face.intercept_declare( &mut Declare { interest_id: None, ext_qos: ext::QoSType::DECLARE, @@ -552,9 +546,9 @@ impl Resource { wire_expr: nonwild_prefix.expr().to_string().into(), }), }, - nonwild_prefix.expr().to_string(), - )); - face.update_interceptors_caches(&mut nonwild_prefix); + Some(&nonwild_prefix), + ); + face.state.update_interceptors_caches(&mut nonwild_prefix); WireExpr { scope: expr_id, suffix: wildsuffix.into(), @@ -761,39 +755,29 @@ impl Resource { } } - pub(crate) fn get_ingress_cache( - &self, - face: &Face, - interceptor: &InterceptorsChain, - ) -> Option { - self.session_ctxs - .get(&face.state.id) - .and_then(|ctx| ctx.in_interceptor_cache.value(interceptor, self)) - } - - pub(crate) fn get_egress_cache( + pub(crate) fn interceptor_cache( &self, - face: &Face, + face: &FaceState, interceptor: &InterceptorsChain, + flow: InterceptorFlow, ) -> Option { - self.session_ctxs - .get(&face.state.id) - .and_then(|ctx| ctx.e_interceptor_cache.value(interceptor, self)) + self.session_ctxs.get(&face.id).and_then(|ctx| { + match flow { + InterceptorFlow::Egress => &ctx.e_interceptor_cache, + InterceptorFlow::Ingress => &ctx.in_interceptor_cache, + } + .value(interceptor, self) + }) } } -pub(crate) fn register_expr( - tables: &TablesLock, - face: &mut Arc, - expr_id: ExprId, - expr: &WireExpr, -) { +pub(crate) fn register_expr(tables: &TablesLock, face: &Face, expr_id: ExprId, expr: &WireExpr) { let rtables = zread!(tables.tables); match rtables - .get_mapping(face, &expr.scope, expr.mapping) + .get_mapping(&face.state, expr.scope, expr.mapping) .cloned() { - Some(mut prefix) => match face.remote_mappings.get(&expr_id) { + Some(mut prefix) => match face.state.remote_mappings.get(&expr_id) { Some(res) => { let mut fullexpr = prefix.expr().to_string(); fullexpr.push_str(expr.suffix.as_ref()); @@ -831,17 +815,17 @@ pub(crate) fn register_expr( }; let ctx = get_mut_unchecked(&mut res) .session_ctxs - .entry(face.id) + .entry(face.state.id) .or_insert_with(|| Arc::new(SessionContext::new(face.clone()))); get_mut_unchecked(ctx).remote_expr_id = Some(expr_id); - get_mut_unchecked(face) + get_mut_unchecked(&mut face.state.clone()) .remote_mappings .insert(expr_id, res.clone()); disable_matches_data_routes(&mut wtables, &mut res); disable_matches_query_routes(&mut wtables, &mut res); - face.update_interceptors_caches(&mut res); + face.state.update_interceptors_caches(&mut res); drop(wtables); } }, @@ -870,10 +854,7 @@ pub(crate) fn register_expr_interest( ) { if let Some(expr) = expr { let rtables = zread!(tables.tables); - match rtables - .get_mapping(face, &expr.scope, expr.mapping) - .cloned() - { + match rtables.get_mapping(face, expr.scope, expr.mapping).cloned() { Some(mut prefix) => { let res = Resource::get_resource(&prefix, &expr.suffix); let (res, wtables) = if res.as_ref().map(|r| r.context.is_some()).unwrap_or(false) { diff --git a/zenoh/src/net/routing/dispatcher/tables.rs b/zenoh/src/net/routing/dispatcher/tables.rs index a3ab28c4b8..613a1a82ff 100644 --- a/zenoh/src/net/routing/dispatcher/tables.rs +++ b/zenoh/src/net/routing/dispatcher/tables.rs @@ -29,7 +29,7 @@ use zenoh_protocol::{ }; use zenoh_result::ZResult; -use super::face::FaceState; +use super::face::{Face, FaceState}; pub use super::resource::*; use crate::net::{ routing::{ @@ -75,8 +75,8 @@ pub struct Tables { pub(crate) queries_default_timeout: Duration, pub(crate) interests_timeout: Duration, pub(crate) root_res: Arc, - pub(crate) faces: HashMap>, - pub(crate) mcast_groups: Vec>, + pub(crate) faces: HashMap, + pub(crate) mcast_groups: Vec, pub(crate) mcast_faces: Vec>, pub(crate) interceptors: Vec, pub(crate) hat: Box, @@ -136,7 +136,7 @@ impl Tables { pub(crate) fn get_mapping<'a>( &'a self, face: &'a FaceState, - expr_id: &ExprId, + expr_id: ExprId, mapping: Mapping, ) -> Option<&'a Arc> { match expr_id { @@ -149,7 +149,7 @@ impl Tables { pub(crate) fn get_sent_mapping<'a>( &'a self, face: &'a FaceState, - expr_id: &ExprId, + expr_id: ExprId, mapping: Mapping, ) -> Option<&'a Arc> { match expr_id { @@ -159,8 +159,8 @@ impl Tables { } #[inline] - pub(crate) fn get_face(&self, zid: &ZenohIdProto) -> Option<&Arc> { - self.faces.values().find(|face| face.zid == *zid) + pub(crate) fn get_face(&self, zid: &ZenohIdProto) -> Option<&Face> { + self.faces.values().find(|face| face.state.zid == *zid) } pub(crate) fn disable_all_routes(&mut self) { @@ -185,7 +185,8 @@ impl TablesLock { .next_interceptor_version .fetch_add(1, Ordering::SeqCst); tables.faces.values().for_each(|face| { - face.set_interceptors_from_factories(&tables.interceptors, version + 1); + face.state + .set_interceptors_from_factories(&tables.interceptors, version + 1); }); Ok(()) } diff --git a/zenoh/src/net/routing/dispatcher/token.rs b/zenoh/src/net/routing/dispatcher/token.rs index 23625ff8ef..54b7641f46 100644 --- a/zenoh/src/net/routing/dispatcher/token.rs +++ b/zenoh/src/net/routing/dispatcher/token.rs @@ -24,7 +24,7 @@ use zenoh_protocol::{ }; use super::{ - face::FaceState, + face::{Face, FaceState}, tables::{NodeId, TablesLock}, }; use crate::net::routing::{ @@ -36,7 +36,7 @@ use crate::net::routing::{ pub(crate) fn declare_token( hat_code: &(dyn HatTrait + Send + Sync), tables: &TablesLock, - face: &mut Arc, + face: &Face, id: TokenId, expr: &WireExpr, node_id: NodeId, @@ -45,7 +45,7 @@ pub(crate) fn declare_token( ) { let rtables = zread!(tables.tables); match rtables - .get_mapping(face, &expr.scope, expr.mapping) + .get_mapping(&face.state, expr.scope, expr.mapping) .cloned() { Some(mut prefix) => { @@ -111,7 +111,7 @@ pub(crate) fn undeclare_token( } else { let rtables = zread!(tables.tables); match rtables - .get_mapping(face, &expr.wire_expr.scope, expr.wire_expr.mapping) + .get_mapping(face, expr.wire_expr.scope, expr.wire_expr.mapping) .cloned() { Some(mut prefix) => { diff --git a/zenoh/src/net/routing/hat/client/interests.rs b/zenoh/src/net/routing/hat/client/interests.rs index 3256278469..ee551e10a5 100644 --- a/zenoh/src/net/routing/hat/client/interests.rs +++ b/zenoh/src/net/routing/hat/client/interests.rs @@ -26,7 +26,7 @@ use zenoh_sync::get_mut_unchecked; use super::{face_hat, face_hat_mut, token::declare_token_interest, HatCode, HatFace}; use crate::net::routing::{ dispatcher::{ - face::{FaceState, InterestState}, + face::{Face, FaceState, InterestState}, interests::{ CurrentInterest, CurrentInterestCleanup, PendingCurrentInterest, RemoteInterest, }, @@ -34,22 +34,16 @@ use crate::net::routing::{ tables::{Tables, TablesLock}, }, hat::{CurrentFutureTrait, HatInterestTrait, SendDeclare}, - RoutingContext, }; -pub(super) fn interests_new_face(tables: &mut Tables, face: &mut Arc) { - if face.whatami != WhatAmI::Client { - for mut src_face in tables - .faces - .values() - .cloned() - .collect::>>() - { +pub(super) fn interests_new_face(tables: &mut Tables, face: &mut Face) { + if face.state.whatami != WhatAmI::Client { + for mut src_face in tables.faces.values().cloned().collect::>() { for RemoteInterest { res, options, .. } in - face_hat_mut!(&mut src_face).remote_interests.values() + face_hat_mut!(&mut src_face.state).remote_interests.values() { - let id = face_hat!(face).next_id.fetch_add(1, Ordering::SeqCst); - get_mut_unchecked(face).local_interests.insert( + let id = face_hat!(face.state).next_id.fetch_add(1, Ordering::SeqCst); + get_mut_unchecked(&mut face.state).local_interests.insert( id, InterestState { options: *options, @@ -58,7 +52,7 @@ pub(super) fn interests_new_face(tables: &mut Tables, face: &mut Arc) }, ); let wire_expr = res.as_ref().map(|res| Resource::decl_key(res, face, true)); - face.primitives.send_interest(RoutingContext::with_expr( + face.intercept_interest( &mut Interest { id, mode: InterestMode::CurrentFuture, @@ -68,10 +62,8 @@ pub(super) fn interests_new_face(tables: &mut Tables, face: &mut Arc) ext_tstamp: None, ext_nodeid: ext::NodeIdType::DEFAULT, }, - res.as_ref() - .map(|res| res.expr().to_string()) - .unwrap_or_default(), - )); + res.as_ref(), + ); } } } @@ -82,7 +74,7 @@ impl HatInterestTrait for HatCode { &self, tables: &mut Tables, tables_ref: &Arc, - face: &mut Arc, + face: &Face, id: InterestId, res: Option<&mut Arc>, mode: InterestMode, @@ -100,14 +92,16 @@ impl HatInterestTrait for HatCode { send_declare, ) } - face_hat_mut!(face).remote_interests.insert( - id, - RemoteInterest { - res: res.as_ref().map(|res| (*res).clone()), - options, - mode, - }, - ); + face_hat_mut!(&mut face.state.clone()) + .remote_interests + .insert( + id, + RemoteInterest { + res: res.as_ref().map(|res| (*res).clone()), + options, + mode, + }, + ); let interest = Arc::new(CurrentInterest { src_face: face.clone(), @@ -118,19 +112,23 @@ impl HatInterestTrait for HatCode { for dst_face in tables .faces .values_mut() - .filter(|f| f.whatami != WhatAmI::Client) + .filter(|f| f.state.whatami != WhatAmI::Client) { - let id = face_hat!(dst_face).next_id.fetch_add(1, Ordering::SeqCst); - get_mut_unchecked(dst_face).local_interests.insert( - id, - InterestState { - options, - res: res.as_ref().map(|res| (*res).clone()), - finalized: mode == InterestMode::Future, - }, - ); + let id = face_hat!(dst_face.state) + .next_id + .fetch_add(1, Ordering::SeqCst); + get_mut_unchecked(&mut dst_face.state) + .local_interests + .insert( + id, + InterestState { + options, + res: res.as_ref().map(|res| (*res).clone()), + finalized: mode == InterestMode::Future, + }, + ); if mode.current() && options.tokens() { - let dst_face_mut = get_mut_unchecked(dst_face); + let dst_face_mut = get_mut_unchecked(&mut dst_face.state); let cancellation_token = dst_face_mut.task_controller.get_cancellation_token(); let rejection_token = dst_face_mut.task_controller.get_cancellation_token(); dst_face_mut.pending_current_interests.insert( @@ -142,7 +140,7 @@ impl HatInterestTrait for HatCode { }, ); CurrentInterestCleanup::spawn_interest_clean_up_task( - dst_face, + &dst_face.state, tables_ref, id, tables.interests_timeout, @@ -151,7 +149,7 @@ impl HatInterestTrait for HatCode { let wire_expr = res .as_ref() .map(|res| Resource::decl_key(res, dst_face, true)); - dst_face.primitives.send_interest(RoutingContext::with_expr( + dst_face.intercept_interest( &mut Interest { id, mode, @@ -161,10 +159,8 @@ impl HatInterestTrait for HatCode { ext_tstamp: None, ext_nodeid: ext::NodeIdType::DEFAULT, }, - res.as_ref() - .map(|res| res.expr().to_string()) - .unwrap_or_default(), - )); + res.as_deref(), + ); } if mode.current() { @@ -176,26 +172,28 @@ impl HatInterestTrait for HatCode { interest.src_interest_id ); send_declare( - &interest.src_face.primitives, - RoutingContext::new(Declare { + &interest.src_face, + Declare { interest_id: Some(interest.src_interest_id), ext_qos: ext::QoSType::DECLARE, ext_tstamp: None, ext_nodeid: ext::NodeIdType::DEFAULT, body: DeclareBody::DeclareFinal(DeclareFinal), - }), + }, + None, ); } } else { send_declare( - &face.primitives, - RoutingContext::new(Declare { + face, + Declare { interest_id: Some(id), ext_qos: ext::QoSType::DECLARE, ext_tstamp: None, ext_nodeid: ext::NodeIdType::DEFAULT, body: DeclareBody::DeclareFinal(DeclareFinal), - }), + }, + None, ); } } @@ -204,8 +202,8 @@ impl HatInterestTrait for HatCode { fn undeclare_interest(&self, tables: &mut Tables, face: &mut Arc, id: InterestId) { if let Some(interest) = face_hat_mut!(face).remote_interests.remove(&id) { if !tables.faces.values().any(|f| { - f.whatami == WhatAmI::Client - && face_hat!(f) + f.state.whatami == WhatAmI::Client + && face_hat!(f.state) .remote_interests .values() .any(|i| *i == interest) @@ -213,19 +211,20 @@ impl HatInterestTrait for HatCode { for dst_face in tables .faces .values_mut() - .filter(|f| f.whatami != WhatAmI::Client) + .filter(|f| f.state.whatami != WhatAmI::Client) { for id in dst_face + .state .local_interests .keys() .cloned() .collect::>() { - let local_interest = dst_face.local_interests.get(&id).unwrap(); + let local_interest = dst_face.state.local_interests.get(&id).unwrap(); if local_interest.res == interest.res && local_interest.options == interest.options { - dst_face.primitives.send_interest(RoutingContext::with_expr( + dst_face.intercept_interest( &mut Interest { id, mode: InterestMode::Final, @@ -237,13 +236,11 @@ impl HatInterestTrait for HatCode { ext_tstamp: None, ext_nodeid: ext::NodeIdType::DEFAULT, }, - local_interest - .res - .as_ref() - .map(|res| res.expr().to_string()) - .unwrap_or_default(), - )); - get_mut_unchecked(dst_face).local_interests.remove(&id); + local_interest.res.as_ref(), + ); + get_mut_unchecked(&mut dst_face.state) + .local_interests + .remove(&id); } } } diff --git a/zenoh/src/net/routing/hat/client/mod.rs b/zenoh/src/net/routing/hat/client/mod.rs index 2f4331c115..79937b6ea0 100644 --- a/zenoh/src/net/routing/hat/client/mod.rs +++ b/zenoh/src/net/routing/hat/client/mod.rs @@ -104,10 +104,10 @@ impl HatBaseTrait for HatCode { face: &mut Face, send_declare: &mut SendDeclare, ) -> ZResult<()> { - interests_new_face(tables, &mut face.state); - pubsub_new_face(tables, &mut face.state, send_declare); + interests_new_face(tables, face); + pubsub_new_face(tables, face, send_declare); queries_new_face(tables, &mut face.state, send_declare); - token_new_face(tables, &mut face.state, send_declare); + token_new_face(tables, face, send_declare); tables.disable_all_routes(); Ok(()) } @@ -120,10 +120,10 @@ impl HatBaseTrait for HatCode { _transport: &TransportUnicast, send_declare: &mut SendDeclare, ) -> ZResult<()> { - interests_new_face(tables, &mut face.state); - pubsub_new_face(tables, &mut face.state, send_declare); + interests_new_face(tables, face); + pubsub_new_face(tables, face, send_declare); queries_new_face(tables, &mut face.state, send_declare); - token_new_face(tables, &mut face.state, send_declare); + token_new_face(tables, face, send_declare); tables.disable_all_routes(); Ok(()) } diff --git a/zenoh/src/net/routing/hat/client/pubsub.rs b/zenoh/src/net/routing/hat/client/pubsub.rs index 8e1a6a43a7..9c6c91c5a7 100644 --- a/zenoh/src/net/routing/hat/client/pubsub.rs +++ b/zenoh/src/net/routing/hat/client/pubsub.rs @@ -31,47 +31,48 @@ use crate::{ key_expr::KeyExpr, net::routing::{ dispatcher::{ - face::FaceState, + face::{Face, FaceState}, pubsub::SubscriberInfo, resource::{NodeId, Resource, SessionContext}, tables::{Route, RoutingExpr, Tables}, }, hat::{HatPubSubTrait, SendDeclare, Sources}, - RoutingContext, }, }; #[inline] fn propagate_simple_subscription_to( _tables: &mut Tables, - dst_face: &mut Arc, + dst_face: &mut Face, res: &Arc, _sub_info: &SubscriberInfo, - src_face: &mut Arc, + src_face: &Face, send_declare: &mut SendDeclare, ) { - if src_face.id != dst_face.id - && !face_hat!(dst_face).local_subs.contains_key(res) - && (src_face.whatami == WhatAmI::Client || dst_face.whatami == WhatAmI::Client) + if src_face.state.id != dst_face.state.id + && !face_hat!(dst_face.state).local_subs.contains_key(res) + && (src_face.state.whatami == WhatAmI::Client || dst_face.state.whatami == WhatAmI::Client) { - let id = face_hat!(dst_face).next_id.fetch_add(1, Ordering::SeqCst); - face_hat_mut!(dst_face).local_subs.insert(res.clone(), id); + let id = face_hat!(dst_face.state) + .next_id + .fetch_add(1, Ordering::SeqCst); + face_hat_mut!(&mut dst_face.state) + .local_subs + .insert(res.clone(), id); let key_expr = Resource::decl_key(res, dst_face, true); send_declare( - &dst_face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareSubscriber(DeclareSubscriber { - id, - wire_expr: key_expr, - }), - }, - res.expr().to_string(), - ), + dst_face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareSubscriber(DeclareSubscriber { + id, + wire_expr: key_expr, + }), + }, + Some(res.clone()), ); } } @@ -80,15 +81,10 @@ fn propagate_simple_subscription( tables: &mut Tables, res: &Arc, sub_info: &SubscriberInfo, - src_face: &mut Arc, + src_face: &Face, send_declare: &mut SendDeclare, ) { - for mut dst_face in tables - .faces - .values() - .cloned() - .collect::>>() - { + for mut dst_face in tables.faces.values().cloned().collect::>() { propagate_simple_subscription_to( tables, &mut dst_face, @@ -102,7 +98,7 @@ fn propagate_simple_subscription( fn register_simple_subscription( _tables: &mut Tables, - face: &mut Arc, + face: &Face, id: SubscriberId, res: &mut Arc, sub_info: &SubscriberInfo, @@ -110,7 +106,7 @@ fn register_simple_subscription( // Register subscription { let res = get_mut_unchecked(res); - match res.session_ctxs.get_mut(&face.id) { + match res.session_ctxs.get_mut(&face.state.id) { Some(ctx) => { if ctx.subs.is_none() { get_mut_unchecked(ctx).subs = Some(*sub_info); @@ -119,18 +115,20 @@ fn register_simple_subscription( None => { let ctx = res .session_ctxs - .entry(face.id) + .entry(face.state.id) .or_insert_with(|| Arc::new(SessionContext::new(face.clone()))); get_mut_unchecked(ctx).subs = Some(*sub_info); } } } - face_hat_mut!(face).remote_subs.insert(id, res.clone()); + face_hat_mut!(&mut face.state.clone()) + .remote_subs + .insert(id, res.clone()); } fn declare_simple_subscription( tables: &mut Tables, - face: &mut Arc, + face: &Face, id: SubscriberId, res: &mut Arc, sub_info: &SubscriberInfo, @@ -142,7 +140,7 @@ fn declare_simple_subscription( } #[inline] -fn simple_subs(res: &Arc) -> Vec> { +fn simple_subs(res: &Arc) -> Vec { res.session_ctxs .values() .filter_map(|ctx| { @@ -161,22 +159,20 @@ fn propagate_forget_simple_subscription( send_declare: &mut SendDeclare, ) { for face in tables.faces.values_mut() { - if let Some(id) = face_hat_mut!(face).local_subs.remove(res) { + if let Some(id) = face_hat_mut!(&mut face.state).local_subs.remove(res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } } @@ -199,22 +195,20 @@ pub(super) fn undeclare_simple_subscription( } if simple_subs.len() == 1 { let face = &mut simple_subs[0]; - if let Some(id) = face_hat_mut!(face).local_subs.remove(res) { + if let Some(id) = face_hat_mut!(&mut face.state).local_subs.remove(res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } } @@ -237,25 +231,13 @@ fn forget_simple_subscription( pub(super) fn pubsub_new_face( tables: &mut Tables, - face: &mut Arc, + face: &mut Face, send_declare: &mut SendDeclare, ) { let sub_info = SubscriberInfo; - for src_face in tables - .faces - .values() - .cloned() - .collect::>>() - { - for sub in face_hat!(src_face).remote_subs.values() { - propagate_simple_subscription_to( - tables, - face, - sub, - &sub_info, - &mut src_face.clone(), - send_declare, - ); + for src_face in tables.faces.values().cloned().collect::>() { + for sub in face_hat!(src_face.state).remote_subs.values() { + propagate_simple_subscription_to(tables, face, sub, &sub_info, &src_face, send_declare); } } } @@ -264,7 +246,7 @@ impl HatPubSubTrait for HatCode { fn declare_subscription( &self, tables: &mut Tables, - face: &mut Arc, + face: &Face, id: SubscriberId, res: &mut Arc, sub_info: &SubscriberInfo, @@ -290,14 +272,14 @@ impl HatPubSubTrait for HatCode { // Compute the list of known suscriptions (keys) let mut subs = HashMap::new(); for src_face in tables.faces.values() { - for sub in face_hat!(src_face).remote_subs.values() { + for sub in face_hat!(src_face.state).remote_subs.values() { // Insert the key in the list of known suscriptions let srcs = subs.entry(sub.clone()).or_insert_with(Sources::empty); // Append src_face as a suscription source in the proper list - match src_face.whatami { - WhatAmI::Router => srcs.routers.push(src_face.zid), - WhatAmI::Peer => srcs.peers.push(src_face.zid), - WhatAmI::Client => srcs.clients.push(src_face.zid), + match src_face.state.whatami { + WhatAmI::Router => srcs.routers.push(src_face.state.zid), + WhatAmI::Peer => srcs.peers.push(src_face.state.zid), + WhatAmI::Client => srcs.clients.push(src_face.state.zid), } } } @@ -307,14 +289,14 @@ impl HatPubSubTrait for HatCode { fn get_publications(&self, tables: &Tables) -> Vec<(Arc, Sources)> { let mut result = HashMap::new(); for face in tables.faces.values() { - for interest in face_hat!(face).remote_interests.values() { + for interest in face_hat!(face.state).remote_interests.values() { if interest.options.subscribers() { if let Some(res) = interest.res.as_ref() { let sources = result.entry(res.clone()).or_insert_with(Sources::default); - match face.whatami { - WhatAmI::Router => sources.routers.push(face.zid), - WhatAmI::Peer => sources.peers.push(face.zid), - WhatAmI::Client => sources.clients.push(face.zid), + match face.state.whatami { + WhatAmI::Router => sources.routers.push(face.state.zid), + WhatAmI::Peer => sources.peers.push(face.state.zid), + WhatAmI::Client => sources.clients.push(face.state.zid), } } } @@ -353,9 +335,9 @@ impl HatPubSubTrait for HatCode { for face in tables .faces .values() - .filter(|f| f.whatami != WhatAmI::Client) + .filter(|f| f.state.whatami != WhatAmI::Client) { - if !face.local_interests.values().any(|interest| { + if !face.state.local_interests.values().any(|interest| { interest.finalized && interest.options.subscribers() && interest @@ -363,14 +345,14 @@ impl HatPubSubTrait for HatCode { .as_ref() .map(|res| KeyExpr::keyexpr_include(res.expr(), expr.full_expr())) .unwrap_or(true) - }) || face_hat!(face) + }) || face_hat!(face.state) .remote_subs .values() .any(|sub| KeyExpr::keyexpr_intersect(sub.expr(), expr.full_expr())) { - let key_expr = Resource::get_best_key(expr.prefix, expr.suffix, face.id); + let key_expr = Resource::get_best_key(expr.prefix, expr.suffix, face.state.id); route.insert( - face.id, + face.state.id, (face.clone(), key_expr.to_owned(), NodeId::default()), ); } @@ -388,7 +370,7 @@ impl HatPubSubTrait for HatCode { let mres = mres.upgrade().unwrap(); for (sid, context) in &mres.session_ctxs { - if context.subs.is_some() && context.face.whatami == WhatAmI::Client { + if context.subs.is_some() && context.face.state.whatami == WhatAmI::Client { route.entry(*sid).or_insert_with(|| { let key_expr = Resource::get_best_key(expr.prefix, expr.suffix, *sid); (context.face.clone(), key_expr.to_owned(), NodeId::default()) @@ -414,9 +396,9 @@ impl HatPubSubTrait for HatCode { for face in tables .faces .values() - .filter(|f| f.whatami != WhatAmI::Client) + .filter(|f| f.state.whatami != WhatAmI::Client) { - if face.local_interests.values().any(|interest| { + if face.state.local_interests.values().any(|interest| { interest.finalized && interest.options.subscribers() && interest @@ -424,12 +406,12 @@ impl HatPubSubTrait for HatCode { .as_ref() .map(|res| KeyExpr::keyexpr_include(res.expr(), key_expr)) .unwrap_or(true) - }) && face_hat!(face) + }) && face_hat!(face.state) .remote_subs .values() .any(|sub| KeyExpr::keyexpr_intersect(sub.expr(), key_expr)) { - matching_subscriptions.insert(face.id, face.clone()); + matching_subscriptions.insert(face.state.id, face.state.clone()); } } @@ -444,10 +426,10 @@ impl HatPubSubTrait for HatCode { let mres = mres.upgrade().unwrap(); for (sid, context) in &mres.session_ctxs { - if context.subs.is_some() && context.face.whatami == WhatAmI::Client { + if context.subs.is_some() && context.face.state.whatami == WhatAmI::Client { matching_subscriptions .entry(*sid) - .or_insert_with(|| context.face.clone()); + .or_insert_with(|| context.face.state.clone()); } } } diff --git a/zenoh/src/net/routing/hat/client/queries.rs b/zenoh/src/net/routing/hat/client/queries.rs index 855207cd53..918cff814e 100644 --- a/zenoh/src/net/routing/hat/client/queries.rs +++ b/zenoh/src/net/routing/hat/client/queries.rs @@ -37,12 +37,11 @@ use crate::{ key_expr::KeyExpr, net::routing::{ dispatcher::{ - face::FaceState, + face::{Face, FaceState}, resource::{NodeId, Resource, SessionContext}, tables::{QueryTargetQabl, QueryTargetQablSet, RoutingExpr, Tables}, }, hat::{HatQueriesTrait, SendDeclare, Sources}, - RoutingContext, }, }; @@ -61,7 +60,7 @@ fn local_qabl_info( res.session_ctxs .values() .fold(None, |accu, ctx| { - if ctx.face.id != face.id { + if ctx.face.state.id != face.id { if let Some(info) = ctx.qabl.as_ref() { Some(match accu { Some(accu) => merge_qabl_infos(accu, info), @@ -80,48 +79,49 @@ fn local_qabl_info( fn propagate_simple_queryable( tables: &mut Tables, res: &Arc, - src_face: Option<&mut Arc>, + src_face: Option<&Face>, send_declare: &mut SendDeclare, ) { let faces = tables.faces.values().cloned(); for mut dst_face in faces { - let info = local_qabl_info(tables, res, &dst_face); - let current = face_hat!(dst_face).local_qabls.get(res); + let info = local_qabl_info(tables, res, &dst_face.state); + let current = face_hat!(dst_face.state).local_qabls.get(res); if src_face .as_ref() - .map(|src_face| dst_face.id != src_face.id) + .map(|src_face| dst_face.state.id != src_face.state.id) .unwrap_or(true) && (current.is_none() || current.unwrap().1 != info) && src_face .as_ref() .map(|src_face| { - src_face.whatami == WhatAmI::Client || dst_face.whatami == WhatAmI::Client + src_face.state.whatami == WhatAmI::Client + || dst_face.state.whatami == WhatAmI::Client }) .unwrap_or(true) { - let id = current - .map(|c| c.0) - .unwrap_or(face_hat!(dst_face).next_id.fetch_add(1, Ordering::SeqCst)); - face_hat_mut!(&mut dst_face) + let id = current.map(|c| c.0).unwrap_or( + face_hat!(dst_face.state) + .next_id + .fetch_add(1, Ordering::SeqCst), + ); + face_hat_mut!(&mut dst_face.state) .local_qabls .insert(res.clone(), (id, info)); - let key_expr = Resource::decl_key(res, &mut dst_face, true); + let key_expr = Resource::decl_key(res, &dst_face, true); send_declare( - &dst_face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareQueryable(DeclareQueryable { - id, - wire_expr: key_expr, - ext_info: info, - }), - }, - res.expr().to_string(), - ), + &dst_face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareQueryable(DeclareQueryable { + id, + wire_expr: key_expr, + ext_info: info, + }), + }, + Some(res.clone()), ); } } @@ -129,7 +129,7 @@ fn propagate_simple_queryable( fn register_simple_queryable( _tables: &mut Tables, - face: &mut Arc, + face: &Face, id: QueryableId, res: &mut Arc, qabl_info: &QueryableInfoType, @@ -139,17 +139,19 @@ fn register_simple_queryable( let res = get_mut_unchecked(res); get_mut_unchecked( res.session_ctxs - .entry(face.id) + .entry(face.state.id) .or_insert_with(|| Arc::new(SessionContext::new(face.clone()))), ) .qabl = Some(*qabl_info); } - face_hat_mut!(face).remote_qabls.insert(id, res.clone()); + face_hat_mut!(&mut face.state.clone()) + .remote_qabls + .insert(id, res.clone()); } fn declare_simple_queryable( tables: &mut Tables, - face: &mut Arc, + face: &Face, id: QueryableId, res: &mut Arc, qabl_info: &QueryableInfoType, @@ -160,7 +162,7 @@ fn declare_simple_queryable( } #[inline] -fn simple_qabls(res: &Arc) -> Vec> { +fn simple_qabls(res: &Arc) -> Vec { res.session_ctxs .values() .filter_map(|ctx| { @@ -179,22 +181,20 @@ fn propagate_forget_simple_queryable( send_declare: &mut SendDeclare, ) { for face in tables.faces.values_mut() { - if let Some((id, _)) = face_hat_mut!(face).local_qabls.remove(res) { + if let Some((id, _)) = face_hat_mut!(&mut face.state).local_qabls.remove(res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareQueryable(UndeclareQueryable { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareQueryable(UndeclareQueryable { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } } @@ -223,22 +223,20 @@ pub(super) fn undeclare_simple_queryable( } if simple_qabls.len() == 1 { let face = &mut simple_qabls[0]; - if let Some((id, _)) = face_hat_mut!(face).local_qabls.remove(res) { + if let Some((id, _)) = face_hat_mut!(&mut face.state).local_qabls.remove(res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareQueryable(UndeclareQueryable { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareQueryable(UndeclareQueryable { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } } @@ -264,14 +262,9 @@ pub(super) fn queries_new_face( _face: &mut Arc, send_declare: &mut SendDeclare, ) { - for face in tables - .faces - .values() - .cloned() - .collect::>>() - { - for qabl in face_hat!(face).remote_qabls.values() { - propagate_simple_queryable(tables, qabl, Some(&mut face.clone()), send_declare); + for face in tables.faces.values().cloned().collect::>() { + for qabl in face_hat!(face.state).remote_qabls.values() { + propagate_simple_queryable(tables, qabl, Some(&face), send_declare); } } } @@ -284,7 +277,7 @@ impl HatQueriesTrait for HatCode { fn declare_queryable( &self, tables: &mut Tables, - face: &mut Arc, + face: &Face, id: QueryableId, res: &mut Arc, qabl_info: &QueryableInfoType, @@ -310,14 +303,14 @@ impl HatQueriesTrait for HatCode { // Compute the list of known queryables (keys) let mut qabls = HashMap::new(); for src_face in tables.faces.values() { - for qabl in face_hat!(src_face).remote_qabls.values() { + for qabl in face_hat!(src_face.state).remote_qabls.values() { // Insert the key in the list of known queryables let srcs = qabls.entry(qabl.clone()).or_insert_with(Sources::empty); // Append src_face as a queryable source in the proper list - match src_face.whatami { - WhatAmI::Router => srcs.routers.push(src_face.zid), - WhatAmI::Peer => srcs.peers.push(src_face.zid), - WhatAmI::Client => srcs.clients.push(src_face.zid), + match src_face.state.whatami { + WhatAmI::Router => srcs.routers.push(src_face.state.zid), + WhatAmI::Peer => srcs.peers.push(src_face.state.zid), + WhatAmI::Client => srcs.clients.push(src_face.state.zid), } } } @@ -327,14 +320,14 @@ impl HatQueriesTrait for HatCode { fn get_queriers(&self, tables: &Tables) -> Vec<(Arc, Sources)> { let mut result = HashMap::new(); for face in tables.faces.values() { - for interest in face_hat!(face).remote_interests.values() { + for interest in face_hat!(face.state).remote_interests.values() { if interest.options.queryables() { if let Some(res) = interest.res.as_ref() { let sources = result.entry(res.clone()).or_insert_with(Sources::default); - match face.whatami { - WhatAmI::Router => sources.routers.push(face.zid), - WhatAmI::Peer => sources.peers.push(face.zid), - WhatAmI::Client => sources.clients.push(face.zid), + match face.state.whatami { + WhatAmI::Router => sources.routers.push(face.state.zid), + WhatAmI::Peer => sources.peers.push(face.state.zid), + WhatAmI::Client => sources.clients.push(face.state.zid), } } } @@ -373,9 +366,9 @@ impl HatQueriesTrait for HatCode { for face in tables .faces .values() - .filter(|f| f.whatami != WhatAmI::Client) + .filter(|f| f.state.whatami != WhatAmI::Client) { - if !face.local_interests.values().any(|interest| { + if !face.state.local_interests.values().any(|interest| { interest.finalized && interest.options.queryables() && interest @@ -383,12 +376,12 @@ impl HatQueriesTrait for HatCode { .as_ref() .map(|res| KeyExpr::keyexpr_include(res.expr(), expr.full_expr())) .unwrap_or(true) - }) || face_hat!(face) + }) || face_hat!(face.state) .remote_qabls .values() .any(|qbl| KeyExpr::keyexpr_intersect(qbl.expr(), expr.full_expr())) { - let key_expr = Resource::get_best_key(expr.prefix, expr.suffix, face.id); + let key_expr = Resource::get_best_key(expr.prefix, expr.suffix, face.state.id); route.push(QueryTargetQabl { direction: (face.clone(), key_expr.to_owned(), NodeId::default()), info: None, @@ -443,9 +436,9 @@ impl HatQueriesTrait for HatCode { for face in tables .faces .values() - .filter(|f| f.whatami != WhatAmI::Client) + .filter(|f| f.state.whatami != WhatAmI::Client) { - if face.local_interests.values().any(|interest| { + if face.state.local_interests.values().any(|interest| { interest.finalized && interest.options.queryables() && interest @@ -453,13 +446,13 @@ impl HatQueriesTrait for HatCode { .as_ref() .map(|res| KeyExpr::keyexpr_include(res.expr(), key_expr)) .unwrap_or(true) - }) && face_hat!(face) + }) && face_hat!(face.state) .remote_qabls .values() .any(|qbl| match complete { true => { qbl.session_ctxs - .get(&face.id) + .get(&face.state.id) .and_then(|sc| sc.qabl) .is_some_and(|q| q.complete) && KeyExpr::keyexpr_include(qbl.expr(), key_expr) @@ -467,7 +460,7 @@ impl HatQueriesTrait for HatCode { false => KeyExpr::keyexpr_intersect(qbl.expr(), key_expr), }) { - matching_queryables.insert(face.id, face.clone()); + matching_queryables.insert(face.state.id, face.state.clone()); } } @@ -484,7 +477,7 @@ impl HatQueriesTrait for HatCode { continue; } for (sid, context) in &mres.session_ctxs { - if context.face.whatami == WhatAmI::Client + if context.face.state.whatami == WhatAmI::Client && match complete { true => context.qabl.is_some_and(|q| q.complete), false => context.qabl.is_some(), @@ -492,7 +485,7 @@ impl HatQueriesTrait for HatCode { { matching_queryables .entry(*sid) - .or_insert_with(|| context.face.clone()); + .or_insert_with(|| context.face.state.clone()); } } } diff --git a/zenoh/src/net/routing/hat/client/token.rs b/zenoh/src/net/routing/hat/client/token.rs index 613f7af94d..ab80ccae73 100644 --- a/zenoh/src/net/routing/hat/client/token.rs +++ b/zenoh/src/net/routing/hat/client/token.rs @@ -12,7 +12,10 @@ // ZettaScale Zenoh Team, // -use std::sync::{atomic::Ordering, Arc}; +use std::{ + ops::Deref, + sync::{atomic::Ordering, Arc}, +}; use zenoh_config::WhatAmI; use zenoh_protocol::network::{ @@ -25,42 +28,46 @@ use zenoh_sync::get_mut_unchecked; use super::{face_hat, face_hat_mut, HatCode, HatFace}; use crate::net::routing::{ - dispatcher::{face::FaceState, tables::Tables}, + dispatcher::{ + face::{Face, FaceState}, + tables::Tables, + }, hat::{CurrentFutureTrait, HatTokenTrait, SendDeclare}, router::{NodeId, Resource, SessionContext}, - RoutingContext, }; #[inline] fn propagate_simple_token_to( _tables: &mut Tables, - dst_face: &mut Arc, + dst_face: &mut Face, res: &Arc, src_face: &mut Arc, send_declare: &mut SendDeclare, ) { - if (src_face.id != dst_face.id || dst_face.whatami == WhatAmI::Client) - && !face_hat!(dst_face).local_tokens.contains_key(res) - && (src_face.whatami == WhatAmI::Client || dst_face.whatami == WhatAmI::Client) + if (src_face.id != dst_face.state.id || dst_face.state.whatami == WhatAmI::Client) + && !face_hat!(dst_face.state).local_tokens.contains_key(res) + && (src_face.whatami == WhatAmI::Client || dst_face.state.whatami == WhatAmI::Client) { - let id = face_hat!(dst_face).next_id.fetch_add(1, Ordering::SeqCst); - face_hat_mut!(dst_face).local_tokens.insert(res.clone(), id); + let id = face_hat!(dst_face.state) + .next_id + .fetch_add(1, Ordering::SeqCst); + face_hat_mut!(&mut dst_face.state) + .local_tokens + .insert(res.clone(), id); let key_expr = Resource::decl_key(res, dst_face, true); send_declare( - &dst_face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareToken(DeclareToken { - id, - wire_expr: key_expr, - }), - }, - res.expr().to_string(), - ), + dst_face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareToken(DeclareToken { + id, + wire_expr: key_expr, + }), + }, + Some(res.clone()), ); } } @@ -71,26 +78,16 @@ fn propagate_simple_token( src_face: &mut Arc, send_declare: &mut SendDeclare, ) { - for mut dst_face in tables - .faces - .values() - .cloned() - .collect::>>() - { + for mut dst_face in tables.faces.values().cloned().collect::>() { propagate_simple_token_to(tables, &mut dst_face, res, src_face, send_declare); } } -fn register_simple_token( - _tables: &mut Tables, - face: &mut Arc, - id: TokenId, - res: &mut Arc, -) { +fn register_simple_token(_tables: &mut Tables, face: &Face, id: TokenId, res: &mut Arc) { // Register liveliness { let res = get_mut_unchecked(res); - match res.session_ctxs.get_mut(&face.id) { + match res.session_ctxs.get_mut(&face.state.id) { Some(ctx) => { if !ctx.token { get_mut_unchecked(ctx).token = true; @@ -99,18 +96,20 @@ fn register_simple_token( None => { let ctx = res .session_ctxs - .entry(face.id) + .entry(face.state.id) .or_insert_with(|| Arc::new(SessionContext::new(face.clone()))); get_mut_unchecked(ctx).token = true; } } } - face_hat_mut!(face).remote_tokens.insert(id, res.clone()); + face_hat_mut!(&mut face.state.clone()) + .remote_tokens + .insert(id, res.clone()); } fn declare_simple_token( tables: &mut Tables, - face: &mut Arc, + face: &Face, id: TokenId, res: &mut Arc, interest_id: Option, @@ -118,30 +117,29 @@ fn declare_simple_token( ) { if let Some(interest_id) = interest_id { if let Some(interest) = face + .state .pending_current_interests .get(&interest_id) .map(|p| &p.interest) { if interest.mode == InterestMode::CurrentFuture { - register_simple_token(tables, &mut face.clone(), id, res); + register_simple_token(tables, face, id, res); } - let id = make_token_id(res, &mut interest.src_face.clone(), interest.mode); - let wire_expr = Resource::get_best_key(res, "", interest.src_face.id); + let id = make_token_id(res, &mut interest.src_face.state.clone(), interest.mode); + let wire_expr = Resource::get_best_key(res, "", interest.src_face.state.id); send_declare( - &interest.src_face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: Some(interest.src_interest_id), - ext_qos: ext::QoSType::default(), - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::default(), - body: DeclareBody::DeclareToken(DeclareToken { id, wire_expr }), - }, - res.expr().to_string(), - ), + &interest.src_face, + Declare { + interest_id: Some(interest.src_interest_id), + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::DeclareToken(DeclareToken { id, wire_expr }), + }, + Some(res.clone()), ); return; - } else if !face.local_interests.contains_key(&interest_id) { + } else if !face.state.local_interests.contains_key(&interest_id) { tracing::debug!( "Received DeclareToken for {} from {} with unknown interest_id {}. Ignore.", res.expr(), @@ -152,11 +150,11 @@ fn declare_simple_token( } } register_simple_token(tables, face, id, res); - propagate_simple_token(tables, res, face, send_declare); + propagate_simple_token(tables, res, &mut face.state.clone(), send_declare); } #[inline] -fn simple_tokens(res: &Arc) -> Vec> { +fn simple_tokens(res: &Arc) -> Vec { res.session_ctxs .values() .filter_map(|ctx| { @@ -175,24 +173,22 @@ fn propagate_forget_simple_token( send_declare: &mut SendDeclare, ) { for face in tables.faces.values_mut() { - if let Some(id) = face_hat_mut!(face).local_tokens.remove(res) { + if let Some(id) = face_hat_mut!(&mut face.state).local_tokens.remove(res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareToken(UndeclareToken { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareToken(UndeclareToken { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); - } else if face_hat!(face) + } else if face_hat!(face.state) .remote_interests .values() .any(|i| i.options.tokens() && i.matches(res)) @@ -200,22 +196,20 @@ fn propagate_forget_simple_token( // Token has never been declared on this face. // Send an Undeclare with a one shot generated id and a WireExpr ext. send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareToken(UndeclareToken { - id: face_hat!(face).next_id.fetch_add(1, Ordering::SeqCst), - ext_wire_expr: WireExprType { - wire_expr: Resource::get_best_key(res, "", face.id), - }, - }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareToken(UndeclareToken { + id: face_hat!(face.state).next_id.fetch_add(1, Ordering::SeqCst), + ext_wire_expr: WireExprType { + wire_expr: Resource::get_best_key(res, "", face.state.id), + }, + }), + }, + Some(res.clone()), ); } } @@ -242,23 +236,21 @@ pub(super) fn undeclare_simple_token( } if simple_tokens.len() == 1 { let face = &mut simple_tokens[0]; - if face.whatami != WhatAmI::Client { - if let Some(id) = face_hat_mut!(face).local_tokens.remove(res) { + if face.state.whatami != WhatAmI::Client { + if let Some(id) = face_hat_mut!(&mut face.state).local_tokens.remove(res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareToken(UndeclareToken { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareToken(UndeclareToken { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } } @@ -284,19 +276,16 @@ fn forget_simple_token( } } -pub(super) fn token_new_face( - tables: &mut Tables, - face: &mut Arc, - send_declare: &mut SendDeclare, -) { - for src_face in tables - .faces - .values() - .cloned() - .collect::>>() - { - for token in face_hat!(src_face).remote_tokens.values() { - propagate_simple_token_to(tables, face, token, &mut src_face.clone(), send_declare); +pub(super) fn token_new_face(tables: &mut Tables, face: &mut Face, send_declare: &mut SendDeclare) { + for src_face in tables.faces.values().cloned().collect::>() { + for token in face_hat!(src_face.state).remote_tokens.values() { + propagate_simple_token_to( + tables, + face, + token, + &mut src_face.state.clone(), + send_declare, + ); } } } @@ -318,7 +307,7 @@ fn make_token_id(res: &Arc, face: &mut Arc, mode: InterestM pub(crate) fn declare_token_interest( tables: &mut Tables, - face: &mut Arc, + face: &Face, id: InterestId, res: Option<&mut Arc>, mode: InterestMode, @@ -330,54 +319,47 @@ pub(crate) fn declare_token_interest( if let Some(res) = res.as_ref() { if aggregate { if tables.faces.values().any(|src_face| { - face_hat!(src_face) + face_hat!(src_face.state) .remote_tokens .values() .any(|token| token.context.is_some() && token.matches(res)) }) { - let id = make_token_id(res, face, mode); + let id = make_token_id(res, &mut face.state.clone(), mode); let wire_expr = Resource::decl_key(res, face, true); send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareToken(DeclareToken { id, wire_expr }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareToken(DeclareToken { id, wire_expr }), + }, + Some(res.deref().clone()), ); } } else { for src_face in tables .faces .values() - .filter(|f| f.whatami == WhatAmI::Client) + .filter(|f| f.state.whatami == WhatAmI::Client) .cloned() - .collect::>>() + .collect::>() { - for token in face_hat!(src_face).remote_tokens.values() { + for token in face_hat!(src_face.state).remote_tokens.values() { if token.context.is_some() && token.matches(res) { - let id = make_token_id(token, face, mode); + let id = make_token_id(token, &mut face.state.clone(), mode); let wire_expr = Resource::decl_key(token, face, true); send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id, - ext_qos: ext::QoSType::default(), - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::default(), - body: DeclareBody::DeclareToken(DeclareToken { - id, - wire_expr, - }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id, + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::DeclareToken(DeclareToken { id, wire_expr }), + }, + Some(res.deref().clone()), ) } } @@ -387,25 +369,23 @@ pub(crate) fn declare_token_interest( for src_face in tables .faces .values() - .filter(|f| f.whatami == WhatAmI::Client) + .filter(|f| f.state.whatami == WhatAmI::Client) .cloned() - .collect::>>() + .collect::>() { - for token in face_hat!(src_face).remote_tokens.values() { - let id = make_token_id(token, face, mode); + for token in face_hat!(src_face.state).remote_tokens.values() { + let id = make_token_id(token, &mut face.state.clone(), mode); let wire_expr = Resource::decl_key(token, face, true); send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareToken(DeclareToken { id, wire_expr }), - }, - token.expr().to_string(), - ), + face, + Declare { + interest_id, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareToken(DeclareToken { id, wire_expr }), + }, + Some(token.clone()), ); } } @@ -417,7 +397,7 @@ impl HatTokenTrait for HatCode { fn declare_token( &self, tables: &mut Tables, - face: &mut Arc, + face: &Face, id: TokenId, res: &mut Arc, _node_id: NodeId, diff --git a/zenoh/src/net/routing/hat/linkstate_peer/interests.rs b/zenoh/src/net/routing/hat/linkstate_peer/interests.rs index c97fc1960f..8cd02e4ad4 100644 --- a/zenoh/src/net/routing/hat/linkstate_peer/interests.rs +++ b/zenoh/src/net/routing/hat/linkstate_peer/interests.rs @@ -11,7 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // -use std::sync::Arc; +use std::{ops::Deref, sync::Arc}; use zenoh_protocol::network::{ declare::ext, @@ -26,13 +26,12 @@ use super::{ }; use crate::net::routing::{ dispatcher::{ - face::FaceState, + face::{Face, FaceState}, interests::RemoteInterest, resource::Resource, tables::{Tables, TablesLock}, }, hat::{CurrentFutureTrait, HatInterestTrait, SendDeclare}, - RoutingContext, }; impl HatInterestTrait for HatCode { @@ -40,7 +39,7 @@ impl HatInterestTrait for HatCode { &self, tables: &mut Tables, _tables_ref: &Arc, - face: &mut Arc, + face: &Face, id: InterestId, res: Option<&mut Arc>, mode: InterestMode, @@ -81,25 +80,28 @@ impl HatInterestTrait for HatCode { ) } if mode.future() { - face_hat_mut!(face).remote_interests.insert( - id, - RemoteInterest { - res: res.cloned(), - options, - mode, - }, - ); + face_hat_mut!(&mut face.state.clone()) + .remote_interests + .insert( + id, + RemoteInterest { + res: res.as_ref().map(|res| res.deref().clone()), + options, + mode, + }, + ); } if mode.current() { send_declare( - &face.primitives, - RoutingContext::new(Declare { + face, + Declare { interest_id: Some(id), ext_qos: ext::QoSType::DECLARE, ext_tstamp: None, ext_nodeid: ext::NodeIdType::DEFAULT, body: DeclareBody::DeclareFinal(DeclareFinal), - }), + }, + None, ); } } diff --git a/zenoh/src/net/routing/hat/linkstate_peer/pubsub.rs b/zenoh/src/net/routing/hat/linkstate_peer/pubsub.rs index 74bd7e1933..2d2b50cd13 100644 --- a/zenoh/src/net/routing/hat/linkstate_peer/pubsub.rs +++ b/zenoh/src/net/routing/hat/linkstate_peer/pubsub.rs @@ -14,6 +14,7 @@ use std::{ borrow::Cow, collections::{HashMap, HashSet}, + ops::Deref, sync::{atomic::Ordering, Arc}, }; @@ -38,7 +39,7 @@ use super::{ use crate::key_expr::KeyExpr; use crate::net::routing::{ dispatcher::{ - face::FaceState, + face::{Face, FaceState}, interests::RemoteInterest, pubsub::SubscriberInfo, resource::{NodeId, Resource, SessionContext}, @@ -46,7 +47,6 @@ use crate::net::routing::{ }, hat::{CurrentFutureTrait, HatPubSubTrait, SendDeclare, Sources}, router::disable_matches_data_routes, - RoutingContext, }; #[inline] @@ -62,15 +62,15 @@ fn send_sourced_subscription_to_net_children( for child in children { if net.graph.contains_node(*child) { match tables.get_face(&net.graph[*child].zid).cloned() { - Some(mut someface) => { + Some(someface) => { if src_face - .map(|src_face| someface.id != src_face.id) + .map(|src_face| someface.state.id != src_face.id) .unwrap_or(true) { - let push_declaration = push_declaration_profile(&someface); - let key_expr = Resource::decl_key(res, &mut someface, push_declaration); + let push_declaration = push_declaration_profile(&someface.state); + let key_expr = Resource::decl_key(res, &someface, push_declaration); - someface.primitives.send_declare(RoutingContext::with_expr( + someface.intercept_declare( &mut Declare { interest_id: None, ext_qos: ext::QoSType::DECLARE, @@ -83,8 +83,8 @@ fn send_sourced_subscription_to_net_children( wire_expr: key_expr, }), }, - res.expr().to_string(), - )); + Some(res), + ); } } None => tracing::trace!("Unable to find face for zid {}", net.graph[*child].zid), @@ -96,38 +96,41 @@ fn send_sourced_subscription_to_net_children( #[inline] fn propagate_simple_subscription_to( _tables: &mut Tables, - dst_face: &mut Arc, + dst_face: &mut Face, res: &Arc, _sub_info: &SubscriberInfo, src_face: &mut Arc, send_declare: &mut SendDeclare, ) { - if (src_face.id != dst_face.id) - && !face_hat!(dst_face).local_subs.contains_key(res) - && dst_face.whatami == WhatAmI::Client + if (src_face.id != dst_face.state.id) + && !face_hat!(dst_face.state).local_subs.contains_key(res) + && dst_face.state.whatami == WhatAmI::Client { - if dst_face.whatami != WhatAmI::Client { - let id = face_hat!(dst_face).next_id.fetch_add(1, Ordering::SeqCst); - face_hat_mut!(dst_face).local_subs.insert(res.clone(), id); - let key_expr = Resource::decl_key(res, dst_face, push_declaration_profile(dst_face)); + if dst_face.state.whatami != WhatAmI::Client { + let id = face_hat!(dst_face.state) + .next_id + .fetch_add(1, Ordering::SeqCst); + face_hat_mut!(&mut dst_face.state) + .local_subs + .insert(res.clone(), id); + let key_expr = + Resource::decl_key(res, dst_face, push_declaration_profile(&dst_face.state)); send_declare( - &dst_face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareSubscriber(DeclareSubscriber { - id, - wire_expr: key_expr, - }), - }, - res.expr().to_string(), - ), + dst_face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareSubscriber(DeclareSubscriber { + id, + wire_expr: key_expr, + }), + }, + Some(res.clone()), ); } else { - let matching_interests = face_hat!(dst_face) + let matching_interests = face_hat!(dst_face.state) .remote_interests .values() .filter(|i| i.options.subscribers() && i.matches(res)) @@ -145,26 +148,31 @@ fn propagate_simple_subscription_to( } else { res }; - if !face_hat!(dst_face).local_subs.contains_key(res) { - let id = face_hat!(dst_face).next_id.fetch_add(1, Ordering::SeqCst); - face_hat_mut!(dst_face).local_subs.insert(res.clone(), id); - let key_expr = - Resource::decl_key(res, dst_face, push_declaration_profile(dst_face)); + if !face_hat!(dst_face.state).local_subs.contains_key(res) { + let id = face_hat!(dst_face.state) + .next_id + .fetch_add(1, Ordering::SeqCst); + face_hat_mut!(&mut dst_face.state) + .local_subs + .insert(res.clone(), id); + let key_expr = Resource::decl_key( + res, + dst_face, + push_declaration_profile(&dst_face.state), + ); send_declare( - &dst_face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareSubscriber(DeclareSubscriber { - id, - wire_expr: key_expr, - }), - }, - res.expr().to_string(), - ), + dst_face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareSubscriber(DeclareSubscriber { + id, + wire_expr: key_expr, + }), + }, + Some(res.clone()), ); } } @@ -179,12 +187,7 @@ fn propagate_simple_subscription( src_face: &mut Arc, send_declare: &mut SendDeclare, ) { - for mut dst_face in tables - .faces - .values() - .cloned() - .collect::>>() - { + for mut dst_face in tables.faces.values().cloned().collect::>() { propagate_simple_subscription_to( tables, &mut dst_face, @@ -269,7 +272,7 @@ fn declare_linkstatepeer_subscription( fn register_simple_subscription( _tables: &mut Tables, - face: &mut Arc, + face: &Face, id: SubscriberId, res: &mut Arc, sub_info: &SubscriberInfo, @@ -277,7 +280,7 @@ fn register_simple_subscription( // Register subscription { let res = get_mut_unchecked(res); - match res.session_ctxs.get_mut(&face.id) { + match res.session_ctxs.get_mut(&face.state.id) { Some(ctx) => { if ctx.subs.is_none() { get_mut_unchecked(ctx).subs = Some(*sub_info); @@ -286,18 +289,20 @@ fn register_simple_subscription( None => { let ctx = res .session_ctxs - .entry(face.id) + .entry(face.state.id) .or_insert_with(|| Arc::new(SessionContext::new(face.clone()))); get_mut_unchecked(ctx).subs = Some(*sub_info); } } } - face_hat_mut!(face).remote_subs.insert(id, res.clone()); + face_hat_mut!(&mut face.state.clone()) + .remote_subs + .insert(id, res.clone()); } fn declare_simple_subscription( tables: &mut Tables, - face: &mut Arc, + face: &Face, id: SubscriberId, res: &mut Arc, sub_info: &SubscriberInfo, @@ -305,7 +310,14 @@ fn declare_simple_subscription( ) { register_simple_subscription(tables, face, id, res, sub_info); let zid = tables.zid; - register_linkstatepeer_subscription(tables, face, res, sub_info, zid, send_declare); + register_linkstatepeer_subscription( + tables, + &mut face.state.clone(), + res, + sub_info, + zid, + send_declare, + ); } #[inline] @@ -318,7 +330,7 @@ fn remote_linkstatepeer_subs(tables: &Tables, res: &Arc) -> bool { } #[inline] -fn simple_subs(res: &Arc) -> Vec> { +fn simple_subs(res: &Arc) -> Vec { res.session_ctxs .values() .filter_map(|ctx| { @@ -335,7 +347,7 @@ fn simple_subs(res: &Arc) -> Vec> { fn remote_simple_subs(res: &Arc, face: &Arc) -> bool { res.session_ctxs .values() - .any(|ctx| ctx.face.id != face.id && ctx.subs.is_some()) + .any(|ctx| ctx.face.state.id != face.id && ctx.subs.is_some()) } #[inline] @@ -350,15 +362,15 @@ fn send_forget_sourced_subscription_to_net_children( for child in children { if net.graph.contains_node(*child) { match tables.get_face(&net.graph[*child].zid).cloned() { - Some(mut someface) => { + Some(someface) => { if src_face - .map(|src_face| someface.id != src_face.id) + .map(|src_face| someface.state.id != src_face.id) .unwrap_or(true) { - let push_declaration = push_declaration_profile(&someface); - let wire_expr = Resource::decl_key(res, &mut someface, push_declaration); + let push_declaration = push_declaration_profile(&someface.state); + let wire_expr = Resource::decl_key(res, &someface, push_declaration); - someface.primitives.send_declare(RoutingContext::with_expr( + someface.intercept_declare( &mut Declare { interest_id: None, ext_qos: ext::QoSType::DECLARE, @@ -371,8 +383,8 @@ fn send_forget_sourced_subscription_to_net_children( ext_wire_expr: WireExprType { wire_expr }, }), }, - res.expr().to_string(), - )); + Some(res), + ); } } None => tracing::trace!("Unable to find face for zid {}", net.graph[*child].zid), @@ -387,25 +399,23 @@ fn propagate_forget_simple_subscription( send_declare: &mut SendDeclare, ) { for mut face in tables.faces.values().cloned() { - if let Some(id) = face_hat_mut!(&mut face).local_subs.remove(res) { + if let Some(id) = face_hat_mut!(&mut face.state).local_subs.remove(res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + &face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } - for res in face_hat!(face) + for res in face_hat!(face.state) .local_subs .keys() .cloned() @@ -414,25 +424,24 @@ fn propagate_forget_simple_subscription( if !res.context().matches.iter().any(|m| { m.upgrade().is_some_and(|m| { m.context.is_some() - && (remote_simple_subs(&m, &face) || remote_linkstatepeer_subs(tables, &m)) + && (remote_simple_subs(&m, &face.state) + || remote_linkstatepeer_subs(tables, &m)) }) }) { - if let Some(id) = face_hat_mut!(&mut face).local_subs.remove(&res) { + if let Some(id) = face_hat_mut!(&mut face.state).local_subs.remove(&res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + &face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } } @@ -541,27 +550,25 @@ pub(super) fn undeclare_simple_subscription( } if simple_subs.len() == 1 && !linkstatepeer_subs { - let mut face = &mut simple_subs[0]; - if face.whatami != WhatAmI::Client { - if let Some(id) = face_hat_mut!(face).local_subs.remove(res) { + let face = &mut simple_subs[0]; + if face.state.whatami != WhatAmI::Client { + if let Some(id) = face_hat_mut!(&mut face.state).local_subs.remove(res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } - for res in face_hat!(face) + for res in face_hat!(face.state) .local_subs .keys() .cloned() @@ -570,28 +577,24 @@ pub(super) fn undeclare_simple_subscription( if !res.context().matches.iter().any(|m| { m.upgrade().is_some_and(|m| { m.context.is_some() - && (remote_simple_subs(&m, face) + && (remote_simple_subs(&m, &face.state) || remote_linkstatepeer_subs(tables, &m)) }) }) { - if let Some(id) = face_hat_mut!(&mut face).local_subs.remove(&res) { + if let Some(id) = face_hat_mut!(&mut face.state).local_subs.remove(&res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareSubscriber( - UndeclareSubscriber { - id, - ext_wire_expr: WireExprType::null(), - }, - ), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } } @@ -690,79 +693,53 @@ fn make_sub_id(res: &Arc, face: &mut Arc, mode: InterestMod pub(super) fn declare_sub_interest( tables: &mut Tables, - face: &mut Arc, + face: &Face, id: InterestId, res: Option<&mut Arc>, mode: InterestMode, aggregate: bool, send_declare: &mut SendDeclare, ) { - if mode.current() && face.whatami == WhatAmI::Client { + if mode.current() && face.state.whatami == WhatAmI::Client { let interest_id = Some(id); if let Some(res) = res.as_ref() { if aggregate { if hat!(tables).linkstatepeer_subs.iter().any(|sub| { sub.context.is_some() && sub.matches(res) - && (remote_simple_subs(sub, face) || remote_linkstatepeer_subs(tables, sub)) + && (remote_simple_subs(sub, &face.state.clone()) + || remote_linkstatepeer_subs(tables, sub)) }) { - let id = make_sub_id(res, face, mode); - let wire_expr = Resource::decl_key(res, face, push_declaration_profile(face)); + let id = make_sub_id(res, &mut face.state.clone(), mode); + let wire_expr = + Resource::decl_key(res, face, push_declaration_profile(&face.state)); send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareSubscriber(DeclareSubscriber { - id, - wire_expr, - }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareSubscriber(DeclareSubscriber { + id, + wire_expr, + }), + }, + Some(res.deref().clone()), ); } } else { for sub in &hat!(tables).linkstatepeer_subs { if sub.context.is_some() && sub.matches(res) - && (remote_simple_subs(sub, face) || remote_linkstatepeer_subs(tables, sub)) + && (remote_simple_subs(sub, &face.state) + || remote_linkstatepeer_subs(tables, sub)) { - let id = make_sub_id(sub, face, mode); + let id = make_sub_id(sub, &mut face.state.clone(), mode); let wire_expr = - Resource::decl_key(sub, face, push_declaration_profile(face)); + Resource::decl_key(sub, face, push_declaration_profile(&face.state)); send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareSubscriber(DeclareSubscriber { - id, - wire_expr, - }), - }, - sub.expr().to_string(), - ), - ); - } - } - } - } else { - for sub in &hat!(tables).linkstatepeer_subs { - if sub.context.is_some() - && (remote_simple_subs(sub, face) || remote_linkstatepeer_subs(tables, sub)) - { - let id = make_sub_id(sub, face, mode); - let wire_expr = Resource::decl_key(sub, face, push_declaration_profile(face)); - send_declare( - &face.primitives, - RoutingContext::with_expr( + face, Declare { interest_id, ext_qos: ext::QoSType::DECLARE, @@ -773,8 +750,33 @@ pub(super) fn declare_sub_interest( wire_expr, }), }, - sub.expr().to_string(), - ), + Some(sub.clone()), + ); + } + } + } + } else { + for sub in &hat!(tables).linkstatepeer_subs { + if sub.context.is_some() + && (remote_simple_subs(sub, &face.state) + || remote_linkstatepeer_subs(tables, sub)) + { + let id = make_sub_id(sub, &mut face.state.clone(), mode); + let wire_expr = + Resource::decl_key(sub, face, push_declaration_profile(&face.state)); + send_declare( + face, + Declare { + interest_id, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareSubscriber(DeclareSubscriber { + id, + wire_expr, + }), + }, + Some(sub.clone()), ); } } @@ -786,16 +788,23 @@ impl HatPubSubTrait for HatCode { fn declare_subscription( &self, tables: &mut Tables, - face: &mut Arc, + face: &Face, id: SubscriberId, res: &mut Arc, sub_info: &SubscriberInfo, node_id: NodeId, send_declare: &mut SendDeclare, ) { - if face.whatami != WhatAmI::Client { - if let Some(peer) = get_peer(tables, face, node_id) { - declare_linkstatepeer_subscription(tables, face, res, sub_info, peer, send_declare) + if face.state.whatami != WhatAmI::Client { + if let Some(peer) = get_peer(tables, &face.state, node_id) { + declare_linkstatepeer_subscription( + tables, + &mut face.state.clone(), + res, + sub_info, + peer, + send_declare, + ) } } else { declare_simple_subscription(tables, face, id, res, sub_info, send_declare) @@ -844,8 +853,8 @@ impl HatPubSubTrait for HatCode { .session_ctxs .values() .filter_map(|f| { - (f.face.whatami == WhatAmI::Client && f.subs.is_some()) - .then_some(f.face.zid) + (f.face.state.whatami == WhatAmI::Client && f.subs.is_some()) + .then_some(f.face.state.zid) }) .collect(), }, @@ -857,14 +866,14 @@ impl HatPubSubTrait for HatCode { fn get_publications(&self, tables: &Tables) -> Vec<(Arc, Sources)> { let mut result = HashMap::new(); for face in tables.faces.values() { - for interest in face_hat!(face).remote_interests.values() { + for interest in face_hat!(face.state).remote_interests.values() { if interest.options.subscribers() { if let Some(res) = interest.res.as_ref() { let sources = result.entry(res.clone()).or_insert_with(Sources::default); - match face.whatami { - WhatAmI::Router => sources.routers.push(face.zid), - WhatAmI::Peer => sources.peers.push(face.zid), - WhatAmI::Client => sources.clients.push(face.zid), + match face.state.whatami { + WhatAmI::Router => sources.routers.push(face.state.zid), + WhatAmI::Peer => sources.peers.push(face.state.zid), + WhatAmI::Client => sources.clients.push(face.state.zid), } } } @@ -898,11 +907,11 @@ impl HatPubSubTrait for HatCode { { if net.graph.contains_node(direction) { if let Some(face) = tables.get_face(&net.graph[direction].zid) { - route.entry(face.id).or_insert_with(|| { + route.entry(face.state.id).or_insert_with(|| { let key_expr = Resource::get_best_key( expr.prefix, expr.suffix, - face.id, + face.state.id, ); (face.clone(), key_expr.to_owned(), source) }); @@ -961,7 +970,8 @@ impl HatPubSubTrait for HatCode { for (sid, context) in &mres.session_ctxs { if context.subs.is_some() - && (source_type == WhatAmI::Client || context.face.whatami == WhatAmI::Client) + && (source_type == WhatAmI::Client + || context.face.state.whatami == WhatAmI::Client) { route.entry(*sid).or_insert_with(|| { let key_expr = Resource::get_best_key(expr.prefix, expr.suffix, *sid); @@ -972,7 +982,7 @@ impl HatPubSubTrait for HatCode { } for mcast_group in &tables.mcast_groups { route.insert( - mcast_group.id, + mcast_group.state.id, ( mcast_group.clone(), expr.full_expr().to_string().into(), @@ -1004,7 +1014,9 @@ impl HatPubSubTrait for HatCode { if let Some(direction) = net.trees[source].directions[sub_idx.index()] { if net.graph.contains_node(direction) { if let Some(face) = tables.get_face(&net.graph[direction].zid) { - route.entry(face.id).or_insert_with(|| face.clone()); + route + .entry(face.state.id) + .or_insert_with(|| face.state.clone()); } } } @@ -1045,7 +1057,7 @@ impl HatPubSubTrait for HatCode { if context.subs.is_some() { matching_subscriptions .entry(*sid) - .or_insert_with(|| context.face.clone()); + .or_insert_with(|| context.face.state.clone()); } } } diff --git a/zenoh/src/net/routing/hat/linkstate_peer/queries.rs b/zenoh/src/net/routing/hat/linkstate_peer/queries.rs index 367c6ecce0..b258b9f00e 100644 --- a/zenoh/src/net/routing/hat/linkstate_peer/queries.rs +++ b/zenoh/src/net/routing/hat/linkstate_peer/queries.rs @@ -14,6 +14,7 @@ use std::{ borrow::Cow, collections::HashMap, + ops::Deref, sync::{atomic::Ordering, Arc}, }; @@ -44,13 +45,12 @@ use super::{ use crate::key_expr::KeyExpr; use crate::net::routing::{ dispatcher::{ - face::FaceState, + face::{Face, FaceState}, resource::{NodeId, Resource, SessionContext}, tables::{QueryTargetQabl, QueryTargetQablSet, RoutingExpr, Tables}, }, hat::{CurrentFutureTrait, HatQueriesTrait, SendDeclare, Sources}, router::disable_matches_query_routes, - RoutingContext, }; #[inline] @@ -101,7 +101,7 @@ fn local_qabl_info( res.session_ctxs .values() .fold(info, |accu, ctx| { - if ctx.face.id != face.id && ctx.face.whatami != WhatAmI::Peer + if ctx.face.state.id != face.id && ctx.face.state.whatami != WhatAmI::Peer || face.whatami != WhatAmI::Peer { if let Some(info) = ctx.qabl.as_ref() { @@ -132,16 +132,16 @@ fn send_sourced_queryable_to_net_children( for child in children { if net.graph.contains_node(*child) { match tables.get_face(&net.graph[*child].zid).cloned() { - Some(mut someface) => { + Some(someface) => { if src_face .as_ref() - .map(|src_face| someface.id != src_face.id) + .map(|src_face| someface.state.id != src_face.id) .unwrap_or(true) { - let push_declaration = push_declaration_profile(&someface); - let key_expr = Resource::decl_key(res, &mut someface, push_declaration); + let push_declaration = push_declaration_profile(&someface.state); + let key_expr = Resource::decl_key(res, &someface, push_declaration); - someface.primitives.send_declare(RoutingContext::with_expr( + someface.intercept_declare( &mut Declare { interest_id: None, ext_qos: ext::QoSType::DECLARE, @@ -155,8 +155,8 @@ fn send_sourced_queryable_to_net_children( ext_info: *qabl_info, }), }, - res.expr().to_string(), - )); + Some(res), + ); } } None => tracing::trace!("Unable to find face for zid {}", net.graph[*child].zid), @@ -173,43 +173,43 @@ fn propagate_simple_queryable( ) { let faces = tables.faces.values().cloned(); for mut dst_face in faces { - let info = local_qabl_info(tables, res, &dst_face); - let current = face_hat!(dst_face).local_qabls.get(res); + let info = local_qabl_info(tables, res, &dst_face.state); + let current = face_hat!(dst_face.state).local_qabls.get(res); if src_face .as_ref() - .map(|src_face| dst_face.id != src_face.id) + .map(|src_face| dst_face.state.id != src_face.id) .unwrap_or(true) && (current.is_none() || current.unwrap().1 != info) - && dst_face.whatami == WhatAmI::Client - && face_hat!(dst_face) + && dst_face.state.whatami == WhatAmI::Client + && face_hat!(dst_face.state) .remote_interests .values() .any(|i| i.options.queryables() && i.matches(res)) { - let id = current - .map(|c| c.0) - .unwrap_or(face_hat!(dst_face).next_id.fetch_add(1, Ordering::SeqCst)); - face_hat_mut!(&mut dst_face) + let id = current.map(|c| c.0).unwrap_or( + face_hat!(dst_face.state) + .next_id + .fetch_add(1, Ordering::SeqCst), + ); + face_hat_mut!(&mut dst_face.state) .local_qabls .insert(res.clone(), (id, info)); - let push_declaration = push_declaration_profile(&dst_face); - let key_expr = Resource::decl_key(res, &mut dst_face, push_declaration); + let push_declaration = push_declaration_profile(&dst_face.state); + let key_expr = Resource::decl_key(res, &dst_face, push_declaration); send_declare( - &dst_face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareQueryable(DeclareQueryable { - id, - wire_expr: key_expr, - ext_info: info, - }), - }, - res.expr().to_string(), - ), + &dst_face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareQueryable(DeclareQueryable { + id, + wire_expr: key_expr, + ext_info: info, + }), + }, + Some(res.clone()), ); } } @@ -292,7 +292,7 @@ fn declare_linkstatepeer_queryable( fn register_simple_queryable( _tables: &mut Tables, - face: &mut Arc, + face: &Face, id: QueryableId, res: &mut Arc, qabl_info: &QueryableInfoType, @@ -302,17 +302,19 @@ fn register_simple_queryable( let res = get_mut_unchecked(res); get_mut_unchecked( res.session_ctxs - .entry(face.id) + .entry(face.state.id) .or_insert_with(|| Arc::new(SessionContext::new(face.clone()))), ) .qabl = Some(*qabl_info); } - face_hat_mut!(face).remote_qabls.insert(id, res.clone()); + face_hat_mut!(&mut face.state.clone()) + .remote_qabls + .insert(id, res.clone()); } fn declare_simple_queryable( tables: &mut Tables, - face: &mut Arc, + face: &Face, id: QueryableId, res: &mut Arc, qabl_info: &QueryableInfoType, @@ -321,7 +323,14 @@ fn declare_simple_queryable( register_simple_queryable(tables, face, id, res, qabl_info); let local_details = local_peer_qabl_info(tables, res); let zid = tables.zid; - register_linkstatepeer_queryable(tables, Some(face), res, &local_details, zid, send_declare); + register_linkstatepeer_queryable( + tables, + Some(&mut face.state.clone()), + res, + &local_details, + zid, + send_declare, + ); } #[inline] @@ -334,7 +343,7 @@ fn remote_linkstatepeer_qabls(tables: &Tables, res: &Arc) -> bool { } #[inline] -fn simple_qabls(res: &Arc) -> Vec> { +fn simple_qabls(res: &Arc) -> Vec { res.session_ctxs .values() .filter_map(|ctx| { @@ -351,7 +360,7 @@ fn simple_qabls(res: &Arc) -> Vec> { fn remote_simple_qabls(res: &Arc, face: &Arc) -> bool { res.session_ctxs .values() - .any(|ctx| ctx.face.id != face.id && ctx.qabl.is_some()) + .any(|ctx| ctx.face.state.id != face.id && ctx.qabl.is_some()) } #[inline] @@ -366,15 +375,15 @@ fn send_forget_sourced_queryable_to_net_children( for child in children { if net.graph.contains_node(*child) { match tables.get_face(&net.graph[*child].zid).cloned() { - Some(mut someface) => { + Some(someface) => { if src_face - .map(|src_face| someface.id != src_face.id) + .map(|src_face| someface.state.id != src_face.id) .unwrap_or(true) { - let push_declaration = push_declaration_profile(&someface); - let wire_expr = Resource::decl_key(res, &mut someface, push_declaration); + let push_declaration = push_declaration_profile(&someface.state); + let wire_expr = Resource::decl_key(res, &someface, push_declaration); - someface.primitives.send_declare(RoutingContext::with_expr( + someface.intercept_declare( &mut Declare { interest_id: None, ext_qos: ext::QoSType::DECLARE, @@ -387,8 +396,8 @@ fn send_forget_sourced_queryable_to_net_children( ext_wire_expr: WireExprType { wire_expr }, }), }, - res.expr().to_string(), - )); + Some(res), + ); } } None => tracing::trace!("Unable to find face for zid {}", net.graph[*child].zid), @@ -403,25 +412,23 @@ fn propagate_forget_simple_queryable( send_declare: &mut SendDeclare, ) { for mut face in tables.faces.values().cloned() { - if let Some((id, _)) = face_hat_mut!(&mut face).local_qabls.remove(res) { + if let Some((id, _)) = face_hat_mut!(&mut face.state).local_qabls.remove(res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareQueryable(UndeclareQueryable { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + &face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareQueryable(UndeclareQueryable { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } - for res in face_hat!(&mut face) + for res in face_hat!(&mut face.state) .local_qabls .keys() .cloned() @@ -430,26 +437,24 @@ fn propagate_forget_simple_queryable( if !res.context().matches.iter().any(|m| { m.upgrade().is_some_and(|m| { m.context.is_some() - && (remote_simple_qabls(&m, &face) + && (remote_simple_qabls(&m, &face.state) || remote_linkstatepeer_qabls(tables, &m)) }) }) { - if let Some((id, _)) = face_hat_mut!(&mut face).local_qabls.remove(&res) { + if let Some((id, _)) = face_hat_mut!(&mut face.state).local_qabls.remove(&res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareQueryable(UndeclareQueryable { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + &face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareQueryable(UndeclareQueryable { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } } @@ -565,26 +570,24 @@ pub(super) fn undeclare_simple_queryable( } if simple_qabls.len() == 1 && !linkstatepeer_qabls { - let mut face = &mut simple_qabls[0]; - if let Some((id, _)) = face_hat_mut!(face).local_qabls.remove(res) { + let face = &mut simple_qabls[0]; + if let Some((id, _)) = face_hat_mut!(&mut face.state).local_qabls.remove(res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareQueryable(UndeclareQueryable { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareQueryable(UndeclareQueryable { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } - for res in face_hat!(face) + for res in face_hat!(face.state) .local_qabls .keys() .cloned() @@ -593,26 +596,24 @@ pub(super) fn undeclare_simple_queryable( if !res.context().matches.iter().any(|m| { m.upgrade().is_some_and(|m| { m.context.is_some() - && (remote_simple_qabls(&m, face) + && (remote_simple_qabls(&m, &face.state) || remote_linkstatepeer_qabls(tables, &m)) }) }) { - if let Some((id, _)) = face_hat_mut!(&mut face).local_qabls.remove(&res) { + if let Some((id, _)) = face_hat_mut!(&mut face.state).local_qabls.remove(&res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareQueryable(UndeclareQueryable { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareQueryable(UndeclareQueryable { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } } @@ -711,8 +712,11 @@ fn insert_target_for_qabls( if net.graph.contains_node(direction) { if let Some(face) = tables.get_face(&net.graph[direction].zid) { if net.distances.len() > qabl_idx.index() { - let key_expr = - Resource::get_best_key(expr.prefix, expr.suffix, face.id); + let key_expr = Resource::get_best_key( + expr.prefix, + expr.suffix, + face.state.id, + ); route.push(QueryTargetQabl { direction: (face.clone(), key_expr.to_owned(), source), info: Some(QueryableInfoType { @@ -760,86 +764,56 @@ fn make_qabl_id( pub(super) fn declare_qabl_interest( tables: &mut Tables, - face: &mut Arc, + face: &Face, id: InterestId, res: Option<&mut Arc>, mode: InterestMode, aggregate: bool, send_declare: &mut SendDeclare, ) { - if mode.current() && face.whatami == WhatAmI::Client { + if mode.current() && face.state.whatami == WhatAmI::Client { let interest_id = Some(id); if let Some(res) = res.as_ref() { if aggregate { if hat!(tables).linkstatepeer_qabls.iter().any(|qabl| { qabl.context.is_some() && qabl.matches(res) - && (remote_simple_qabls(qabl, face) + && (remote_simple_qabls(qabl, &face.state) || remote_linkstatepeer_qabls(tables, qabl)) }) { - let info = local_qabl_info(tables, res, face); - let id = make_qabl_id(res, face, mode, info); - let wire_expr = Resource::decl_key(res, face, push_declaration_profile(face)); + let info = local_qabl_info(tables, res, &face.state); + let id = make_qabl_id(res, &mut face.state.clone(), mode, info); + let wire_expr = + Resource::decl_key(res, face, push_declaration_profile(&face.state)); send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareQueryable(DeclareQueryable { - id, - wire_expr, - ext_info: info, - }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareQueryable(DeclareQueryable { + id, + wire_expr, + ext_info: info, + }), + }, + Some(res.deref().clone()), ); } } else { for qabl in hat!(tables).linkstatepeer_qabls.iter() { if qabl.context.is_some() && qabl.matches(res) - && (remote_simple_qabls(qabl, face) + && (remote_simple_qabls(qabl, &face.state) || remote_linkstatepeer_qabls(tables, qabl)) { - let info = local_qabl_info(tables, qabl, face); - let id = make_qabl_id(qabl, face, mode, info); + let info = local_qabl_info(tables, qabl, &face.state); + let id = make_qabl_id(qabl, &mut face.state.clone(), mode, info); let key_expr = - Resource::decl_key(qabl, face, push_declaration_profile(face)); + Resource::decl_key(qabl, face, push_declaration_profile(&face.state)); send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareQueryable(DeclareQueryable { - id, - wire_expr: key_expr, - ext_info: info, - }), - }, - qabl.expr().to_string(), - ), - ); - } - } - } - } else { - for qabl in hat!(tables).linkstatepeer_qabls.iter() { - if qabl.context.is_some() - && (remote_simple_qabls(qabl, face) || remote_linkstatepeer_qabls(tables, qabl)) - { - let info = local_qabl_info(tables, qabl, face); - let id = make_qabl_id(qabl, face, mode, info); - let key_expr = Resource::decl_key(qabl, face, push_declaration_profile(face)); - send_declare( - &face.primitives, - RoutingContext::with_expr( + face, Declare { interest_id, ext_qos: ext::QoSType::DECLARE, @@ -851,8 +825,35 @@ pub(super) fn declare_qabl_interest( ext_info: info, }), }, - qabl.expr().to_string(), - ), + Some(qabl.clone()), + ); + } + } + } + } else { + for qabl in hat!(tables).linkstatepeer_qabls.iter() { + if qabl.context.is_some() + && (remote_simple_qabls(qabl, &face.state) + || remote_linkstatepeer_qabls(tables, qabl)) + { + let info = local_qabl_info(tables, qabl, &face.state); + let id = make_qabl_id(qabl, &mut face.state.clone(), mode, info); + let key_expr = + Resource::decl_key(qabl, face, push_declaration_profile(&face.state)); + send_declare( + face, + Declare { + interest_id, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareQueryable(DeclareQueryable { + id, + wire_expr: key_expr, + ext_info: info, + }), + }, + Some(qabl.clone()), ); } } @@ -864,16 +865,23 @@ impl HatQueriesTrait for HatCode { fn declare_queryable( &self, tables: &mut Tables, - face: &mut Arc, + face: &Face, id: QueryableId, res: &mut Arc, qabl_info: &QueryableInfoType, node_id: NodeId, send_declare: &mut SendDeclare, ) { - if face.whatami != WhatAmI::Client { - if let Some(peer) = get_peer(tables, face, node_id) { - declare_linkstatepeer_queryable(tables, face, res, qabl_info, peer, send_declare); + if face.state.whatami != WhatAmI::Client { + if let Some(peer) = get_peer(tables, &face.state, node_id) { + declare_linkstatepeer_queryable( + tables, + &mut face.state.clone(), + res, + qabl_info, + peer, + send_declare, + ); } } else { declare_simple_queryable(tables, face, id, res, qabl_info, send_declare); @@ -922,8 +930,8 @@ impl HatQueriesTrait for HatCode { .session_ctxs .values() .filter_map(|f| { - (f.face.whatami == WhatAmI::Client && f.qabl.is_some()) - .then_some(f.face.zid) + (f.face.state.whatami == WhatAmI::Client && f.qabl.is_some()) + .then_some(f.face.state.zid) }) .collect(), }, @@ -935,14 +943,14 @@ impl HatQueriesTrait for HatCode { fn get_queriers(&self, tables: &Tables) -> Vec<(Arc, Sources)> { let mut result = HashMap::new(); for face in tables.faces.values() { - for interest in face_hat!(face).remote_interests.values() { + for interest in face_hat!(face.state).remote_interests.values() { if interest.options.queryables() { if let Some(res) = interest.res.as_ref() { let sources = result.entry(res.clone()).or_insert_with(Sources::default); - match face.whatami { - WhatAmI::Router => sources.routers.push(face.zid), - WhatAmI::Peer => sources.peers.push(face.zid), - WhatAmI::Client => sources.clients.push(face.zid), + match face.state.whatami { + WhatAmI::Router => sources.routers.push(face.state.zid), + WhatAmI::Peer => sources.peers.push(face.state.zid), + WhatAmI::Client => sources.clients.push(face.state.zid), } } } @@ -1003,7 +1011,7 @@ impl HatQueriesTrait for HatCode { ); for (sid, context) in &mres.session_ctxs { - if source_type == WhatAmI::Client || context.face.whatami == WhatAmI::Client { + if source_type == WhatAmI::Client || context.face.state.whatami == WhatAmI::Client { let key_expr = Resource::get_best_key(expr.prefix, expr.suffix, *sid); if let Some(qabl_info) = context.qabl.as_ref() { route.push(QueryTargetQabl { @@ -1071,7 +1079,7 @@ impl HatQueriesTrait for HatCode { } { matching_queryables .entry(*sid) - .or_insert_with(|| context.face.clone()); + .or_insert_with(|| context.face.state.clone()); } } } @@ -1099,7 +1107,9 @@ fn insert_faces_for_qbls( if let Some(direction) = net.trees[source].directions[qbl_idx.index()] { if net.graph.contains_node(direction) { if let Some(face) = tables.get_face(&net.graph[direction].zid) { - route.entry(face.id).or_insert_with(|| face.clone()); + route + .entry(face.state.id) + .or_insert_with(|| face.state.clone()); } } } diff --git a/zenoh/src/net/routing/hat/linkstate_peer/token.rs b/zenoh/src/net/routing/hat/linkstate_peer/token.rs index 853a711ece..53b3fd9b2c 100644 --- a/zenoh/src/net/routing/hat/linkstate_peer/token.rs +++ b/zenoh/src/net/routing/hat/linkstate_peer/token.rs @@ -12,7 +12,10 @@ // ZettaScale Zenoh Team, // -use std::sync::{atomic::Ordering, Arc}; +use std::{ + ops::Deref, + sync::{atomic::Ordering, Arc}, +}; use petgraph::graph::NodeIndex; use zenoh_protocol::{ @@ -31,10 +34,13 @@ use super::{ res_hat, res_hat_mut, HatCode, HatContext, HatFace, HatTables, }; use crate::net::routing::{ - dispatcher::{face::FaceState, interests::RemoteInterest, tables::Tables}, + dispatcher::{ + face::{Face, FaceState}, + interests::RemoteInterest, + tables::Tables, + }, hat::{CurrentFutureTrait, HatTokenTrait, SendDeclare}, router::{NodeId, Resource, SessionContext}, - RoutingContext, }; #[inline] @@ -49,15 +55,15 @@ fn send_sourced_token_to_net_clildren( for child in clildren { if net.graph.contains_node(*child) { match tables.get_face(&net.graph[*child].zid).cloned() { - Some(mut someface) => { + Some(someface) => { if src_face - .map(|src_face| someface.id != src_face.id) + .map(|src_face| someface.state.id != src_face.id) .unwrap_or(true) { - let push_declaration = push_declaration_profile(&someface); - let key_expr = Resource::decl_key(res, &mut someface, push_declaration); + let push_declaration = push_declaration_profile(&someface.state); + let key_expr = Resource::decl_key(res, &someface, push_declaration); - someface.primitives.send_declare(RoutingContext::with_expr( + someface.intercept_declare( &mut Declare { interest_id: None, ext_qos: ext::QoSType::DECLARE, @@ -70,8 +76,8 @@ fn send_sourced_token_to_net_clildren( wire_expr: key_expr, }), }, - res.expr().to_string(), - )); + Some(res), + ); } } None => tracing::trace!("Unable to find face for zid {}", net.graph[*child].zid), @@ -83,37 +89,40 @@ fn send_sourced_token_to_net_clildren( #[inline] fn propagate_simple_token_to( tables: &mut Tables, - dst_face: &mut Arc, + dst_face: &mut Face, res: &Arc, src_face: &mut Arc, send_declare: &mut SendDeclare, ) { - if (src_face.id != dst_face.id || dst_face.zid == tables.zid) - && !face_hat!(dst_face).local_tokens.contains_key(res) - && dst_face.whatami == WhatAmI::Client + if (src_face.id != dst_face.state.id || dst_face.state.zid == tables.zid) + && !face_hat!(dst_face.state).local_tokens.contains_key(res) + && dst_face.state.whatami == WhatAmI::Client { - if dst_face.whatami != WhatAmI::Client { - let id = face_hat!(dst_face).next_id.fetch_add(1, Ordering::SeqCst); - face_hat_mut!(dst_face).local_tokens.insert(res.clone(), id); - let key_expr = Resource::decl_key(res, dst_face, push_declaration_profile(dst_face)); + if dst_face.state.whatami != WhatAmI::Client { + let id = face_hat!(dst_face.state) + .next_id + .fetch_add(1, Ordering::SeqCst); + face_hat_mut!(&mut dst_face.state) + .local_tokens + .insert(res.clone(), id); + let key_expr = + Resource::decl_key(res, dst_face, push_declaration_profile(&dst_face.state)); send_declare( - &dst_face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareToken(DeclareToken { - id, - wire_expr: key_expr, - }), - }, - res.expr().to_string(), - ), + dst_face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareToken(DeclareToken { + id, + wire_expr: key_expr, + }), + }, + Some(res.clone()), ); } else { - let matching_interests = face_hat!(dst_face) + let matching_interests = face_hat!(dst_face.state) .remote_interests .values() .filter(|i| i.options.tokens() && i.matches(res)) @@ -131,26 +140,31 @@ fn propagate_simple_token_to( } else { res }; - if !face_hat!(dst_face).local_tokens.contains_key(res) { - let id = face_hat!(dst_face).next_id.fetch_add(1, Ordering::SeqCst); - face_hat_mut!(dst_face).local_tokens.insert(res.clone(), id); - let key_expr = - Resource::decl_key(res, dst_face, push_declaration_profile(dst_face)); + if !face_hat!(dst_face.state).local_tokens.contains_key(res) { + let id = face_hat!(dst_face.state) + .next_id + .fetch_add(1, Ordering::SeqCst); + face_hat_mut!(&mut dst_face.state) + .local_tokens + .insert(res.clone(), id); + let key_expr = Resource::decl_key( + res, + dst_face, + push_declaration_profile(&dst_face.state), + ); send_declare( - &dst_face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareToken(DeclareToken { - id, - wire_expr: key_expr, - }), - }, - res.expr().to_string(), - ), + dst_face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareToken(DeclareToken { + id, + wire_expr: key_expr, + }), + }, + Some(res.clone()), ); } } @@ -164,12 +178,7 @@ fn propagate_simple_token( src_face: &mut Arc, send_declare: &mut SendDeclare, ) { - for mut dst_face in tables - .faces - .values() - .cloned() - .collect::>>() - { + for mut dst_face in tables.faces.values().cloned().collect::>() { propagate_simple_token_to(tables, &mut dst_face, res, src_face, send_declare); } } @@ -241,16 +250,11 @@ fn declare_linkstatepeer_token( register_linkstatepeer_token(tables, face, res, peer, send_declare); } -fn register_simple_token( - _tables: &mut Tables, - face: &mut Arc, - id: TokenId, - res: &mut Arc, -) { +fn register_simple_token(_tables: &mut Tables, face: &Face, id: TokenId, res: &mut Arc) { // Register liveliness { let res = get_mut_unchecked(res); - match res.session_ctxs.get_mut(&face.id) { + match res.session_ctxs.get_mut(&face.state.id) { Some(ctx) => { if !ctx.token { get_mut_unchecked(ctx).token = true; @@ -259,25 +263,27 @@ fn register_simple_token( None => { let ctx = res .session_ctxs - .entry(face.id) + .entry(face.state.id) .or_insert_with(|| Arc::new(SessionContext::new(face.clone()))); get_mut_unchecked(ctx).token = true; } } } - face_hat_mut!(face).remote_tokens.insert(id, res.clone()); + face_hat_mut!(&mut face.state.clone()) + .remote_tokens + .insert(id, res.clone()); } fn declare_simple_token( tables: &mut Tables, - face: &mut Arc, + face: &Face, id: TokenId, res: &mut Arc, send_declare: &mut SendDeclare, ) { register_simple_token(tables, face, id, res); let zid = tables.zid; - register_linkstatepeer_token(tables, face, res, zid, send_declare); + register_linkstatepeer_token(tables, &mut face.state.clone(), res, zid, send_declare); } #[inline] @@ -290,7 +296,7 @@ fn remote_linkstatepeer_tokens(tables: &Tables, res: &Arc) -> bool { } #[inline] -fn simple_tokens(res: &Arc) -> Vec> { +fn simple_tokens(res: &Arc) -> Vec { res.session_ctxs .values() .filter_map(|ctx| { @@ -307,7 +313,7 @@ fn simple_tokens(res: &Arc) -> Vec> { fn remote_simple_tokens(tables: &Tables, res: &Arc, face: &Arc) -> bool { res.session_ctxs .values() - .any(|ctx| (ctx.face.id != face.id || face.zid == tables.zid) && ctx.token) + .any(|ctx| (ctx.face.state.id != face.id || face.zid == tables.zid) && ctx.token) } #[inline] @@ -322,15 +328,15 @@ fn send_forget_sourced_token_to_net_clildren( for child in clildren { if net.graph.contains_node(*child) { match tables.get_face(&net.graph[*child].zid).cloned() { - Some(mut someface) => { + Some(someface) => { if src_face - .map(|src_face| someface.id != src_face.id) + .map(|src_face| someface.state.id != src_face.id) .unwrap_or(true) { - let push_declaration = push_declaration_profile(&someface); - let wire_expr = Resource::decl_key(res, &mut someface, push_declaration); + let push_declaration = push_declaration_profile(&someface.state); + let wire_expr = Resource::decl_key(res, &someface, push_declaration); - someface.primitives.send_declare(RoutingContext::with_expr( + someface.intercept_declare( &mut Declare { interest_id: None, ext_qos: ext::QoSType::DECLARE, @@ -343,8 +349,8 @@ fn send_forget_sourced_token_to_net_clildren( ext_wire_expr: WireExprType { wire_expr }, }), }, - res.expr().to_string(), - )); + Some(res), + ); } } None => tracing::trace!("Unable to find face for zid {}", net.graph[*child].zid), @@ -359,25 +365,23 @@ fn propagate_forget_simple_token( send_declare: &mut SendDeclare, ) { for mut face in tables.faces.values().cloned() { - if let Some(id) = face_hat_mut!(&mut face).local_tokens.remove(res) { + if let Some(id) = face_hat_mut!(&mut face.state).local_tokens.remove(res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareToken(UndeclareToken { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + &face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareToken(UndeclareToken { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } - for res in face_hat!(face) + for res in face_hat!(face.state) .local_tokens .keys() .cloned() @@ -386,26 +390,24 @@ fn propagate_forget_simple_token( if !res.context().matches.iter().any(|m| { m.upgrade().is_some_and(|m| { m.context.is_some() - && (remote_simple_tokens(tables, &m, &face) + && (remote_simple_tokens(tables, &m, &face.state) || remote_linkstatepeer_tokens(tables, &m)) }) }) { - if let Some(id) = face_hat_mut!(&mut face).local_tokens.remove(&res) { + if let Some(id) = face_hat_mut!(&mut face.state).local_tokens.remove(&res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareToken(UndeclareToken { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + &face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareToken(UndeclareToken { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } } @@ -512,27 +514,25 @@ pub(super) fn undeclare_simple_token( } if simple_tokens.len() == 1 && !linkstatepeer_tokens { - let mut face = &mut simple_tokens[0]; - if face.whatami != WhatAmI::Client { - if let Some(id) = face_hat_mut!(face).local_tokens.remove(res) { + let face = &mut simple_tokens[0]; + if face.state.whatami != WhatAmI::Client { + if let Some(id) = face_hat_mut!(&mut face.state).local_tokens.remove(res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareToken(UndeclareToken { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareToken(UndeclareToken { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } - for res in face_hat!(face) + for res in face_hat!(face.state) .local_tokens .keys() .cloned() @@ -541,26 +541,24 @@ pub(super) fn undeclare_simple_token( if !res.context().matches.iter().any(|m| { m.upgrade().is_some_and(|m| { m.context.is_some() - && (remote_simple_tokens(tables, &m, face) + && (remote_simple_tokens(tables, &m, &face.state) || remote_linkstatepeer_tokens(tables, &m)) }) }) { - if let Some(id) = face_hat_mut!(&mut face).local_tokens.remove(&res) { + if let Some(id) = face_hat_mut!(&mut face.state).local_tokens.remove(&res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareToken(UndeclareToken { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareToken(UndeclareToken { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } } @@ -655,61 +653,58 @@ fn make_token_id(res: &Arc, face: &mut Arc, mode: InterestM pub(crate) fn declare_token_interest( tables: &mut Tables, - face: &mut Arc, + face: &Face, id: InterestId, res: Option<&mut Arc>, mode: InterestMode, aggregate: bool, send_declare: &mut SendDeclare, ) { - if mode.current() && face.whatami == WhatAmI::Client { + if mode.current() && face.state.whatami == WhatAmI::Client { let interest_id = Some(id); if let Some(res) = res.as_ref() { if aggregate { if hat!(tables).linkstatepeer_tokens.iter().any(|token| { token.context.is_some() && token.matches(res) - && (remote_simple_tokens(tables, token, face) + && (remote_simple_tokens(tables, token, &face.state) || remote_linkstatepeer_tokens(tables, token)) }) { - let id = make_token_id(res, face, mode); - let wire_expr = Resource::decl_key(res, face, push_declaration_profile(face)); + let id = make_token_id(res, &mut face.state.clone(), mode); + let wire_expr = + Resource::decl_key(res, face, push_declaration_profile(&face.state)); send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareToken(DeclareToken { id, wire_expr }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareToken(DeclareToken { id, wire_expr }), + }, + Some(res.deref().clone()), ); } } else { for token in &hat!(tables).linkstatepeer_tokens { if token.context.is_some() && token.matches(res) - && (remote_simple_tokens(tables, token, face) + && (remote_simple_tokens(tables, token, &face.state) || remote_linkstatepeer_tokens(tables, token)) { - let id = make_token_id(token, face, mode); + let id = make_token_id(token, &mut face.state.clone(), mode); let wire_expr = - Resource::decl_key(token, face, push_declaration_profile(face)); + Resource::decl_key(token, face, push_declaration_profile(&face.state)); send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareToken(DeclareToken { id, wire_expr }), - }, - token.expr().to_string(), - ), + face, + Declare { + interest_id, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareToken(DeclareToken { id, wire_expr }), + }, + Some(token.clone()), ); } } @@ -717,23 +712,22 @@ pub(crate) fn declare_token_interest( } else { for token in &hat!(tables).linkstatepeer_tokens { if token.context.is_some() - && (remote_simple_tokens(tables, token, face) + && (remote_simple_tokens(tables, token, &face.state) || remote_linkstatepeer_tokens(tables, token)) { - let id = make_token_id(token, face, mode); - let wire_expr = Resource::decl_key(token, face, push_declaration_profile(face)); + let id = make_token_id(token, &mut face.state.clone(), mode); + let wire_expr = + Resource::decl_key(token, face, push_declaration_profile(&face.state)); send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareToken(DeclareToken { id, wire_expr }), - }, - token.expr().to_string(), - ), + face, + Declare { + interest_id, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareToken(DeclareToken { id, wire_expr }), + }, + Some(token.clone()), ); } } @@ -745,16 +739,22 @@ impl HatTokenTrait for HatCode { fn declare_token( &self, tables: &mut Tables, - face: &mut Arc, + face: &Face, id: TokenId, res: &mut Arc, node_id: NodeId, _interest_id: Option, send_declare: &mut SendDeclare, ) { - if face.whatami != WhatAmI::Client { - if let Some(peer) = get_peer(tables, face, node_id) { - declare_linkstatepeer_token(tables, face, res, peer, send_declare) + if face.state.whatami != WhatAmI::Client { + if let Some(peer) = get_peer(tables, &face.state, node_id) { + declare_linkstatepeer_token( + tables, + &mut face.state.clone(), + res, + peer, + send_declare, + ) } } else { declare_simple_token(tables, face, id, res, send_declare) diff --git a/zenoh/src/net/routing/hat/mod.rs b/zenoh/src/net/routing/hat/mod.rs index 00f74721d6..bf1d94203b 100644 --- a/zenoh/src/net/routing/hat/mod.rs +++ b/zenoh/src/net/routing/hat/mod.rs @@ -33,13 +33,10 @@ use zenoh_transport::unicast::TransportUnicast; #[cfg(feature = "unstable")] use {crate::key_expr::KeyExpr, std::collections::HashMap}; -use super::{ - dispatcher::{ - face::{Face, FaceState}, - pubsub::SubscriberInfo, - tables::{NodeId, QueryTargetQablSet, Resource, Route, RoutingExpr, Tables, TablesLock}, - }, - RoutingContext, +use super::dispatcher::{ + face::{Face, FaceState}, + pubsub::SubscriberInfo, + tables::{NodeId, QueryTargetQablSet, Resource, Route, RoutingExpr, Tables, TablesLock}, }; use crate::net::runtime::Runtime; @@ -69,8 +66,7 @@ impl Sources { } } -pub(crate) type SendDeclare<'a> = dyn FnMut(&Arc, RoutingContext) - + 'a; +pub(crate) type SendDeclare<'a> = dyn FnMut(&Face, Declare, Option>) + 'a; pub(crate) trait HatTrait: HatBaseTrait + HatInterestTrait + HatPubSubTrait + HatQueriesTrait + HatTokenTrait { @@ -145,7 +141,7 @@ pub(crate) trait HatInterestTrait { &self, tables: &mut Tables, tables_ref: &Arc, - face: &mut Arc, + face: &Face, id: InterestId, res: Option<&mut Arc>, mode: InterestMode, @@ -161,7 +157,7 @@ pub(crate) trait HatPubSubTrait { fn declare_subscription( &self, tables: &mut Tables, - face: &mut Arc, + face: &Face, id: SubscriberId, res: &mut Arc, sub_info: &SubscriberInfo, @@ -203,7 +199,7 @@ pub(crate) trait HatQueriesTrait { fn declare_queryable( &self, tables: &mut Tables, - face: &mut Arc, + face: &Face, id: QueryableId, res: &mut Arc, qabl_info: &QueryableInfoType, @@ -260,7 +256,7 @@ pub(crate) trait HatTokenTrait { fn declare_token( &self, tables: &mut Tables, - face: &mut Arc, + face: &Face, id: TokenId, res: &mut Arc, node_id: NodeId, diff --git a/zenoh/src/net/routing/hat/p2p_peer/interests.rs b/zenoh/src/net/routing/hat/p2p_peer/interests.rs index adb3ea683a..94f7b45080 100644 --- a/zenoh/src/net/routing/hat/p2p_peer/interests.rs +++ b/zenoh/src/net/routing/hat/p2p_peer/interests.rs @@ -30,7 +30,7 @@ use super::{ }; use crate::net::routing::{ dispatcher::{ - face::{FaceState, InterestState}, + face::{Face, FaceState, InterestState}, interests::{ CurrentInterest, CurrentInterestCleanup, PendingCurrentInterest, RemoteInterest, }, @@ -38,34 +38,30 @@ use crate::net::routing::{ tables::{Tables, TablesLock}, }, hat::{CurrentFutureTrait, HatInterestTrait, SendDeclare}, - RoutingContext, }; -pub(super) fn interests_new_face(tables: &mut Tables, face: &mut Arc) { - if face.whatami != WhatAmI::Client { - for mut src_face in tables - .faces - .values() - .cloned() - .collect::>>() - { - if face.whatami == WhatAmI::Router { +pub(super) fn interests_new_face(tables: &mut Tables, face: &Face) { + if face.state.whatami != WhatAmI::Client { + for mut src_face in tables.faces.values().cloned().collect::>() { + if face.state.whatami == WhatAmI::Router { for RemoteInterest { res, options, .. } in - face_hat_mut!(&mut src_face).remote_interests.values() + face_hat_mut!(&mut src_face.state).remote_interests.values() { - let id = face_hat!(face).next_id.fetch_add(1, Ordering::SeqCst); - get_mut_unchecked(face).local_interests.insert( - id, - InterestState { - options: *options, - res: res.as_ref().map(|res| (*res).clone()), - finalized: false, - }, - ); + let id = face_hat!(face.state).next_id.fetch_add(1, Ordering::SeqCst); + get_mut_unchecked(&mut face.state.clone()) + .local_interests + .insert( + id, + InterestState { + options: *options, + res: res.as_ref().map(|res| (*res).clone()), + finalized: false, + }, + ); let wire_expr = res.as_ref().map(|res| { - Resource::decl_key(res, face, super::push_declaration_profile(face)) + Resource::decl_key(res, face, super::push_declaration_profile(&face.state)) }); - face.primitives.send_interest(RoutingContext::with_expr( + face.intercept_interest( &mut Interest { id, mode: InterestMode::CurrentFuture, @@ -75,10 +71,8 @@ pub(super) fn interests_new_face(tables: &mut Tables, face: &mut Arc) ext_tstamp: None, ext_nodeid: ext::NodeIdType::DEFAULT, }, - res.as_ref() - .map(|res| res.expr().to_string()) - .unwrap_or_default(), - )); + res.as_ref(), + ); } } } @@ -90,7 +84,7 @@ impl HatInterestTrait for HatCode { &self, tables: &mut Tables, tables_ref: &Arc, - face: &mut Arc, + face: &Face, id: InterestId, res: Option<&mut Arc>, mode: InterestMode, @@ -130,14 +124,16 @@ impl HatInterestTrait for HatCode { send_declare, ) } - face_hat_mut!(face).remote_interests.insert( - id, - RemoteInterest { - res: res.as_ref().map(|res| (*res).clone()), - options, - mode, - }, - ); + face_hat_mut!(&mut face.state.clone()) + .remote_interests + .insert( + id, + RemoteInterest { + res: res.as_ref().map(|res| (*res).clone()), + options, + mode, + }, + ); let interest = Arc::new(CurrentInterest { src_face: face.clone(), @@ -145,30 +141,36 @@ impl HatInterestTrait for HatCode { mode, }); - if face.whatami == WhatAmI::Client { + if face.state.whatami == WhatAmI::Client { let propagated_mode = if mode.future() { InterestMode::CurrentFuture } else { mode }; for dst_face in tables.faces.values_mut().filter(|f| { - f.whatami == WhatAmI::Router - || (f.whatami == WhatAmI::Peer + f.state.whatami == WhatAmI::Router + || (f.state.whatami == WhatAmI::Peer && options.tokens() && mode == InterestMode::Current - && !initial_interest(f).map(|i| i.finalized).unwrap_or(true)) + && !initial_interest(&f.state) + .map(|i| i.finalized) + .unwrap_or(true)) }) { - let id = face_hat!(dst_face).next_id.fetch_add(1, Ordering::SeqCst); - get_mut_unchecked(dst_face).local_interests.insert( - id, - InterestState { - options, - res: res.as_ref().map(|res| (*res).clone()), - finalized: propagated_mode == InterestMode::Future, - }, - ); + let id = face_hat!(dst_face.state) + .next_id + .fetch_add(1, Ordering::SeqCst); + get_mut_unchecked(&mut dst_face.state) + .local_interests + .insert( + id, + InterestState { + options, + res: res.as_ref().map(|res| (*res).clone()), + finalized: propagated_mode == InterestMode::Future, + }, + ); if mode.current() { - let dst_face_mut = get_mut_unchecked(dst_face); + let dst_face_mut = get_mut_unchecked(&mut dst_face.state); let cancellation_token = dst_face_mut.task_controller.get_cancellation_token(); let rejection_token = dst_face_mut.task_controller.get_cancellation_token(); dst_face_mut.pending_current_interests.insert( @@ -180,16 +182,20 @@ impl HatInterestTrait for HatCode { }, ); CurrentInterestCleanup::spawn_interest_clean_up_task( - dst_face, + &dst_face.state, tables_ref, id, tables.interests_timeout, ); } let wire_expr = res.as_ref().map(|res| { - Resource::decl_key(res, dst_face, super::push_declaration_profile(dst_face)) + Resource::decl_key( + res, + dst_face, + super::push_declaration_profile(&dst_face.state), + ) }); - dst_face.primitives.send_interest(RoutingContext::with_expr( + dst_face.intercept_interest( &mut Interest { id, mode: propagated_mode, @@ -199,10 +205,8 @@ impl HatInterestTrait for HatCode { ext_tstamp: None, ext_nodeid: ext::NodeIdType::DEFAULT, }, - res.as_ref() - .map(|res| res.expr().to_string()) - .unwrap_or_default(), - )); + res.as_deref(), + ); } } @@ -214,14 +218,15 @@ impl HatInterestTrait for HatCode { interest.src_interest_id ); send_declare( - &interest.src_face.primitives, - RoutingContext::new(Declare { + &interest.src_face, + Declare { interest_id: Some(interest.src_interest_id), ext_qos: ext::QoSType::DECLARE, ext_tstamp: None, ext_nodeid: ext::NodeIdType::DEFAULT, body: DeclareBody::DeclareFinal(DeclareFinal), - }), + }, + None, ); } } @@ -230,8 +235,8 @@ impl HatInterestTrait for HatCode { fn undeclare_interest(&self, tables: &mut Tables, face: &mut Arc, id: InterestId) { if let Some(interest) = face_hat_mut!(face).remote_interests.remove(&id) { if !tables.faces.values().any(|f| { - f.whatami == WhatAmI::Client - && face_hat!(f) + f.state.whatami == WhatAmI::Client + && face_hat!(f.state) .remote_interests .values() .any(|i| *i == interest) @@ -239,19 +244,20 @@ impl HatInterestTrait for HatCode { for dst_face in tables .faces .values_mut() - .filter(|f| f.whatami == WhatAmI::Router) + .filter(|f| f.state.whatami == WhatAmI::Router) { for id in dst_face + .state .local_interests .keys() .cloned() .collect::>() { - let local_interest = dst_face.local_interests.get(&id).unwrap(); + let local_interest = dst_face.state.local_interests.get(&id).unwrap(); if local_interest.res == interest.res && local_interest.options == interest.options { - dst_face.primitives.send_interest(RoutingContext::with_expr( + dst_face.intercept_interest( &mut Interest { id, mode: InterestMode::Final, @@ -263,13 +269,11 @@ impl HatInterestTrait for HatCode { ext_tstamp: None, ext_nodeid: ext::NodeIdType::DEFAULT, }, - local_interest - .res - .as_ref() - .map(|res| res.expr().to_string()) - .unwrap_or_default(), - )); - get_mut_unchecked(dst_face).local_interests.remove(&id); + local_interest.res.as_ref(), + ); + get_mut_unchecked(&mut dst_face.state) + .local_interests + .remove(&id); } } } diff --git a/zenoh/src/net/routing/hat/p2p_peer/mod.rs b/zenoh/src/net/routing/hat/p2p_peer/mod.rs index 03b9455270..f11bb9cc9c 100644 --- a/zenoh/src/net/routing/hat/p2p_peer/mod.rs +++ b/zenoh/src/net/routing/hat/p2p_peer/mod.rs @@ -59,12 +59,9 @@ use super::{ use crate::net::{ codec::Zenoh080Routing, protocol::linkstate::LinkStateList, - routing::{ - dispatcher::{ - face::{Face, InterestState}, - interests::RemoteInterest, - }, - RoutingContext, + routing::dispatcher::{ + face::{Face, InterestState}, + interests::RemoteInterest, }, runtime::Runtime, }; @@ -166,10 +163,10 @@ impl HatBaseTrait for HatCode { face: &mut Face, send_declare: &mut SendDeclare, ) -> ZResult<()> { - interests_new_face(tables, &mut face.state); - pubsub_new_face(tables, &mut face.state, send_declare); - queries_new_face(tables, &mut face.state, send_declare); - token_new_face(tables, &mut face.state, send_declare); + interests_new_face(tables, face); + pubsub_new_face(tables, face, send_declare); + queries_new_face(tables, face, send_declare); + token_new_face(tables, face, send_declare); tables.disable_all_routes(); Ok(()) } @@ -198,22 +195,23 @@ impl HatBaseTrait for HatCode { ); } - interests_new_face(tables, &mut face.state); - pubsub_new_face(tables, &mut face.state, send_declare); - queries_new_face(tables, &mut face.state, send_declare); - token_new_face(tables, &mut face.state, send_declare); + interests_new_face(tables, face); + pubsub_new_face(tables, face, send_declare); + queries_new_face(tables, face, send_declare); + token_new_face(tables, face, send_declare); tables.disable_all_routes(); if face.state.whatami == WhatAmI::Peer { send_declare( - &face.state.primitives, - RoutingContext::new(Declare { + face, + Declare { interest_id: Some(0), ext_qos: QoSType::default(), ext_tstamp: None, ext_nodeid: NodeIdType::default(), body: DeclareBody::DeclareFinal(DeclareFinal), - }), + }, + None, ); } Ok(()) diff --git a/zenoh/src/net/routing/hat/p2p_peer/pubsub.rs b/zenoh/src/net/routing/hat/p2p_peer/pubsub.rs index 8a84906c3c..f6709e48c7 100644 --- a/zenoh/src/net/routing/hat/p2p_peer/pubsub.rs +++ b/zenoh/src/net/routing/hat/p2p_peer/pubsub.rs @@ -14,6 +14,7 @@ use std::{ borrow::Cow, collections::HashMap, + ops::Deref, sync::{atomic::Ordering, Arc}, }; @@ -34,7 +35,7 @@ use crate::{ key_expr::KeyExpr, net::routing::{ dispatcher::{ - face::FaceState, + face::{Face, FaceState}, interests::RemoteInterest, pubsub::SubscriberInfo, resource::{NodeId, Resource, SessionContext}, @@ -43,46 +44,50 @@ use crate::{ hat::{ p2p_peer::initial_interest, CurrentFutureTrait, HatPubSubTrait, SendDeclare, Sources, }, - RoutingContext, }, }; #[inline] fn propagate_simple_subscription_to( _tables: &mut Tables, - dst_face: &mut Arc, + dst_face: &mut Face, res: &Arc, _sub_info: &SubscriberInfo, - src_face: &mut Arc, + src_face: &Face, send_declare: &mut SendDeclare, ) { - if (src_face.id != dst_face.id) - && !face_hat!(dst_face).local_subs.contains_key(res) - && (src_face.whatami == WhatAmI::Client || dst_face.whatami == WhatAmI::Client) + if (src_face.state.id != dst_face.state.id) + && !face_hat!(dst_face.state).local_subs.contains_key(res) + && (src_face.state.whatami == WhatAmI::Client || dst_face.state.whatami == WhatAmI::Client) { - if dst_face.whatami != WhatAmI::Client { - let id = face_hat!(dst_face).next_id.fetch_add(1, Ordering::SeqCst); - face_hat_mut!(dst_face).local_subs.insert(res.clone(), id); - let key_expr = - Resource::decl_key(res, dst_face, super::push_declaration_profile(dst_face)); + if dst_face.state.whatami != WhatAmI::Client { + let id = face_hat!(dst_face.state) + .next_id + .fetch_add(1, Ordering::SeqCst); + face_hat_mut!(&mut dst_face.state) + .local_subs + .insert(res.clone(), id); + let key_expr = Resource::decl_key( + res, + dst_face, + super::push_declaration_profile(&dst_face.state), + ); send_declare( - &dst_face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareSubscriber(DeclareSubscriber { - id, - wire_expr: key_expr, - }), - }, - res.expr().to_string(), - ), + dst_face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareSubscriber(DeclareSubscriber { + id, + wire_expr: key_expr, + }), + }, + Some(res.clone()), ); } else { - let matching_interests = face_hat!(dst_face) + let matching_interests = face_hat!(dst_face.state) .remote_interests .values() .filter(|i| i.options.subscribers() && i.matches(res)) @@ -100,29 +105,31 @@ fn propagate_simple_subscription_to( } else { res }; - if !face_hat!(dst_face).local_subs.contains_key(res) { - let id = face_hat!(dst_face).next_id.fetch_add(1, Ordering::SeqCst); - face_hat_mut!(dst_face).local_subs.insert(res.clone(), id); + if !face_hat!(dst_face.state).local_subs.contains_key(res) { + let id = face_hat!(dst_face.state) + .next_id + .fetch_add(1, Ordering::SeqCst); + face_hat_mut!(&mut dst_face.state) + .local_subs + .insert(res.clone(), id); let key_expr = Resource::decl_key( res, dst_face, - super::push_declaration_profile(dst_face), + super::push_declaration_profile(&dst_face.state), ); send_declare( - &dst_face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareSubscriber(DeclareSubscriber { - id, - wire_expr: key_expr, - }), - }, - res.expr().to_string(), - ), + dst_face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareSubscriber(DeclareSubscriber { + id, + wire_expr: key_expr, + }), + }, + Some(res.clone()), ); } } @@ -134,15 +141,10 @@ fn propagate_simple_subscription( tables: &mut Tables, res: &Arc, sub_info: &SubscriberInfo, - src_face: &mut Arc, + src_face: &Face, send_declare: &mut SendDeclare, ) { - for mut dst_face in tables - .faces - .values() - .cloned() - .collect::>>() - { + for mut dst_face in tables.faces.values().cloned().collect::>() { propagate_simple_subscription_to( tables, &mut dst_face, @@ -156,7 +158,7 @@ fn propagate_simple_subscription( fn register_simple_subscription( _tables: &mut Tables, - face: &mut Arc, + face: &Face, id: SubscriberId, res: &mut Arc, sub_info: &SubscriberInfo, @@ -164,7 +166,7 @@ fn register_simple_subscription( // Register subscription { let res = get_mut_unchecked(res); - match res.session_ctxs.get_mut(&face.id) { + match res.session_ctxs.get_mut(&face.state.id) { Some(ctx) => { if ctx.subs.is_none() { get_mut_unchecked(ctx).subs = Some(*sub_info); @@ -173,18 +175,20 @@ fn register_simple_subscription( None => { let ctx = res .session_ctxs - .entry(face.id) + .entry(face.state.id) .or_insert_with(|| Arc::new(SessionContext::new(face.clone()))); get_mut_unchecked(ctx).subs = Some(*sub_info); } } } - face_hat_mut!(face).remote_subs.insert(id, res.clone()); + face_hat_mut!(&mut face.state.clone()) + .remote_subs + .insert(id, res.clone()); } fn declare_simple_subscription( tables: &mut Tables, - face: &mut Arc, + face: &Face, id: SubscriberId, res: &mut Arc, sub_info: &SubscriberInfo, @@ -196,31 +200,29 @@ fn declare_simple_subscription( // This introduced a buffer overflow on windows // TODO: Let's deactivate this on windows until Fixed #[cfg(not(windows))] - if face.whatami == WhatAmI::Client { + if face.state.whatami == WhatAmI::Client { for mcast_group in &tables.mcast_groups { - if mcast_group.mcast_group != face.mcast_group { - mcast_group - .primitives - .send_declare(RoutingContext::with_expr( - &mut Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareSubscriber(DeclareSubscriber { - id: 0, // @TODO use proper SubscriberId - wire_expr: res.expr().to_string().into(), - }), - }, - res.expr().to_string(), - )) + if mcast_group.state.mcast_group != face.state.mcast_group { + mcast_group.intercept_declare( + &mut Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareSubscriber(DeclareSubscriber { + id: 0, // @TODO use proper SubscriberId + wire_expr: res.expr().to_string().into(), + }), + }, + Some(res), + ) } } } } #[inline] -fn simple_subs(res: &Arc) -> Vec> { +fn simple_subs(res: &Arc) -> Vec { res.session_ctxs .values() .filter_map(|ctx| { @@ -237,7 +239,7 @@ fn simple_subs(res: &Arc) -> Vec> { fn remote_simple_subs(res: &Arc, face: &Arc) -> bool { res.session_ctxs .values() - .any(|ctx| ctx.face.id != face.id && ctx.subs.is_some()) + .any(|ctx| ctx.face.state.id != face.id && ctx.subs.is_some()) } fn propagate_forget_simple_subscription( @@ -246,25 +248,23 @@ fn propagate_forget_simple_subscription( send_declare: &mut SendDeclare, ) { for mut face in tables.faces.values().cloned() { - if let Some(id) = face_hat_mut!(&mut face).local_subs.remove(res) { + if let Some(id) = face_hat_mut!(&mut face.state).local_subs.remove(res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + &face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } - for res in face_hat!(face) + for res in face_hat!(face.state) .local_subs .keys() .cloned() @@ -272,24 +272,22 @@ fn propagate_forget_simple_subscription( { if !res.context().matches.iter().any(|m| { m.upgrade() - .is_some_and(|m| m.context.is_some() && remote_simple_subs(&m, &face)) + .is_some_and(|m| m.context.is_some() && remote_simple_subs(&m, &face.state)) }) { - if let Some(id) = face_hat_mut!(&mut face).local_subs.remove(&res) { + if let Some(id) = face_hat_mut!(&mut face.state).local_subs.remove(&res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + &face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } } @@ -314,26 +312,24 @@ pub(super) fn undeclare_simple_subscription( } if simple_subs.len() == 1 { - let mut face = &mut simple_subs[0]; - if let Some(id) = face_hat_mut!(face).local_subs.remove(res) { + let face = &mut simple_subs[0]; + if let Some(id) = face_hat_mut!(&mut face.state).local_subs.remove(res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } - for res in face_hat!(face) + for res in face_hat!(face.state) .local_subs .keys() .cloned() @@ -341,24 +337,22 @@ pub(super) fn undeclare_simple_subscription( { if !res.context().matches.iter().any(|m| { m.upgrade() - .is_some_and(|m| m.context.is_some() && remote_simple_subs(&m, face)) + .is_some_and(|m| m.context.is_some() && remote_simple_subs(&m, &face.state)) }) { - if let Some(id) = face_hat_mut!(&mut face).local_subs.remove(&res) { + if let Some(id) = face_hat_mut!(&mut face.state).local_subs.remove(&res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } } @@ -383,24 +377,19 @@ fn forget_simple_subscription( pub(super) fn pubsub_new_face( tables: &mut Tables, - face: &mut Arc, + face: &mut Face, send_declare: &mut SendDeclare, ) { - if face.whatami != WhatAmI::Client { + if face.state.whatami != WhatAmI::Client { let sub_info = SubscriberInfo; - for src_face in tables - .faces - .values() - .cloned() - .collect::>>() - { - for sub in face_hat!(src_face).remote_subs.values() { + for src_face in tables.faces.values().cloned().collect::>() { + for sub in face_hat!(src_face.state).remote_subs.values() { propagate_simple_subscription_to( tables, face, sub, &sub_info, - &mut src_face.clone(), + &src_face, send_declare, ); } @@ -425,74 +414,66 @@ fn make_sub_id(res: &Arc, face: &mut Arc, mode: InterestMod pub(super) fn declare_sub_interest( tables: &mut Tables, - face: &mut Arc, + face: &Face, id: InterestId, res: Option<&mut Arc>, mode: InterestMode, aggregate: bool, send_declare: &mut SendDeclare, ) { - if mode.current() && face.whatami == WhatAmI::Client { + if mode.current() && face.state.whatami == WhatAmI::Client { let interest_id = Some(id); if let Some(res) = res.as_ref() { if aggregate { if tables.faces.values().any(|src_face| { - src_face.id != face.id - && face_hat!(src_face) + src_face.state.id != face.state.id + && face_hat!(src_face.state) .remote_subs .values() .any(|sub| sub.context.is_some() && sub.matches(res)) }) { - let id = make_sub_id(res, face, mode); + let id = make_sub_id(res, &mut face.state.clone(), mode); let wire_expr = - Resource::decl_key(res, face, super::push_declaration_profile(face)); + Resource::decl_key(res, face, super::push_declaration_profile(&face.state)); send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareSubscriber(DeclareSubscriber { - id, - wire_expr, - }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareSubscriber(DeclareSubscriber { + id, + wire_expr, + }), + }, + Some(res.deref().clone()), ); } } else { - for src_face in tables - .faces - .values() - .cloned() - .collect::>>() - { - if src_face.id != face.id { - for sub in face_hat!(src_face).remote_subs.values() { + for src_face in tables.faces.values().cloned().collect::>() { + if src_face.state.id != face.state.id { + for sub in face_hat!(src_face.state).remote_subs.values() { if sub.context.is_some() && sub.matches(res) { - let id = make_sub_id(sub, face, mode); + let id = make_sub_id(sub, &mut face.state.clone(), mode); let wire_expr = Resource::decl_key( sub, face, - super::push_declaration_profile(face), + super::push_declaration_profile(&face.state), ); send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareSubscriber( - DeclareSubscriber { id, wire_expr }, - ), - }, - sub.expr().to_string(), - ), + face, + Declare { + interest_id, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareSubscriber(DeclareSubscriber { + id, + wire_expr, + }), + }, + Some(sub.clone()), ); } } @@ -500,32 +481,28 @@ pub(super) fn declare_sub_interest( } } } else { - for src_face in tables - .faces - .values() - .cloned() - .collect::>>() - { - if src_face.id != face.id { - for sub in face_hat!(src_face).remote_subs.values() { - let id = make_sub_id(sub, face, mode); - let wire_expr = - Resource::decl_key(sub, face, super::push_declaration_profile(face)); + for src_face in tables.faces.values().cloned().collect::>() { + if src_face.state.id != face.state.id { + for sub in face_hat!(src_face.state).remote_subs.values() { + let id = make_sub_id(sub, &mut face.state.clone(), mode); + let wire_expr = Resource::decl_key( + sub, + face, + super::push_declaration_profile(&face.state), + ); send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareSubscriber(DeclareSubscriber { - id, - wire_expr, - }), - }, - sub.expr().to_string(), - ), + face, + Declare { + interest_id, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareSubscriber(DeclareSubscriber { + id, + wire_expr, + }), + }, + Some(sub.clone()), ); } } @@ -538,7 +515,7 @@ impl HatPubSubTrait for HatCode { fn declare_subscription( &self, tables: &mut Tables, - face: &mut Arc, + face: &Face, id: SubscriberId, res: &mut Arc, sub_info: &SubscriberInfo, @@ -564,14 +541,14 @@ impl HatPubSubTrait for HatCode { // Compute the list of known suscriptions (keys) let mut subs = HashMap::new(); for src_face in tables.faces.values() { - for sub in face_hat!(src_face).remote_subs.values() { + for sub in face_hat!(src_face.state).remote_subs.values() { // Insert the key in the list of known suscriptions let srcs = subs.entry(sub.clone()).or_insert_with(Sources::empty); // Append src_face as a suscription source in the proper list - match src_face.whatami { - WhatAmI::Router => srcs.routers.push(src_face.zid), - WhatAmI::Peer => srcs.peers.push(src_face.zid), - WhatAmI::Client => srcs.clients.push(src_face.zid), + match src_face.state.whatami { + WhatAmI::Router => srcs.routers.push(src_face.state.zid), + WhatAmI::Peer => srcs.peers.push(src_face.state.zid), + WhatAmI::Client => srcs.clients.push(src_face.state.zid), } } } @@ -581,14 +558,14 @@ impl HatPubSubTrait for HatCode { fn get_publications(&self, tables: &Tables) -> Vec<(Arc, Sources)> { let mut result = HashMap::new(); for face in tables.faces.values() { - for interest in face_hat!(face).remote_interests.values() { + for interest in face_hat!(face.state).remote_interests.values() { if interest.options.subscribers() { if let Some(res) = interest.res.as_ref() { let sources = result.entry(res.clone()).or_insert_with(Sources::default); - match face.whatami { - WhatAmI::Router => sources.routers.push(face.zid), - WhatAmI::Peer => sources.peers.push(face.zid), - WhatAmI::Client => sources.clients.push(face.zid), + match face.state.whatami { + WhatAmI::Router => sources.routers.push(face.state.zid), + WhatAmI::Peer => sources.peers.push(face.state.zid), + WhatAmI::Client => sources.clients.push(face.state.zid), } } } @@ -627,9 +604,9 @@ impl HatPubSubTrait for HatCode { for face in tables .faces .values() - .filter(|f| f.whatami == WhatAmI::Router) + .filter(|f| f.state.whatami == WhatAmI::Router) { - if !face.local_interests.values().any(|interest| { + if !face.state.local_interests.values().any(|interest| { interest.finalized && interest.options.subscribers() && interest @@ -637,25 +614,27 @@ impl HatPubSubTrait for HatCode { .as_ref() .map(|res| KeyExpr::keyexpr_include(res.expr(), expr.full_expr())) .unwrap_or(true) - }) || face_hat!(face) + }) || face_hat!(face.state) .remote_subs .values() .any(|sub| KeyExpr::keyexpr_intersect(sub.expr(), expr.full_expr())) { - let key_expr = Resource::get_best_key(expr.prefix, expr.suffix, face.id); + let key_expr = Resource::get_best_key(expr.prefix, expr.suffix, face.state.id); route.insert( - face.id, + face.state.id, (face.clone(), key_expr.to_owned(), NodeId::default()), ); } } for face in tables.faces.values().filter(|f| { - f.whatami == WhatAmI::Peer - && !initial_interest(f).map(|i| i.finalized).unwrap_or(true) + f.state.whatami == WhatAmI::Peer + && !initial_interest(&f.state) + .map(|i| i.finalized) + .unwrap_or(true) }) { - route.entry(face.id).or_insert_with(|| { - let key_expr = Resource::get_best_key(expr.prefix, expr.suffix, face.id); + route.entry(face.state.id).or_insert_with(|| { + let key_expr = Resource::get_best_key(expr.prefix, expr.suffix, face.state.id); (face.clone(), key_expr.to_owned(), NodeId::default()) }); } @@ -673,7 +652,8 @@ impl HatPubSubTrait for HatCode { for (sid, context) in &mres.session_ctxs { if context.subs.is_some() - && (source_type == WhatAmI::Client || context.face.whatami == WhatAmI::Client) + && (source_type == WhatAmI::Client + || context.face.state.whatami == WhatAmI::Client) { route.entry(*sid).or_insert_with(|| { let key_expr = Resource::get_best_key(expr.prefix, expr.suffix, *sid); @@ -684,7 +664,7 @@ impl HatPubSubTrait for HatCode { } for mcast_group in &tables.mcast_groups { route.insert( - mcast_group.id, + mcast_group.state.id, ( mcast_group.clone(), expr.full_expr().to_string().into(), @@ -720,7 +700,7 @@ impl HatPubSubTrait for HatCode { if context.subs.is_some() { matching_subscriptions .entry(*sid) - .or_insert_with(|| context.face.clone()); + .or_insert_with(|| context.face.state.clone()); } } } diff --git a/zenoh/src/net/routing/hat/p2p_peer/queries.rs b/zenoh/src/net/routing/hat/p2p_peer/queries.rs index 0119cfdaf8..10206b25f6 100644 --- a/zenoh/src/net/routing/hat/p2p_peer/queries.rs +++ b/zenoh/src/net/routing/hat/p2p_peer/queries.rs @@ -14,6 +14,7 @@ use std::{ borrow::Cow, collections::HashMap, + ops::Deref, sync::{atomic::Ordering, Arc}, }; @@ -40,14 +41,13 @@ use crate::{ key_expr::KeyExpr, net::routing::{ dispatcher::{ - face::FaceState, + face::{Face, FaceState}, resource::{NodeId, Resource, SessionContext}, tables::{QueryTargetQabl, QueryTargetQablSet, RoutingExpr, Tables}, }, hat::{ p2p_peer::initial_interest, CurrentFutureTrait, HatQueriesTrait, SendDeclare, Sources, }, - RoutingContext, }, }; @@ -66,7 +66,7 @@ fn local_qabl_info( res.session_ctxs .values() .fold(None, |accu, ctx| { - if ctx.face.id != face.id { + if ctx.face.state.id != face.id { if let Some(info) = ctx.qabl.as_ref() { Some(match accu { Some(accu) => merge_qabl_infos(accu, info), @@ -85,53 +85,58 @@ fn local_qabl_info( #[inline] fn propagate_simple_queryable_to( tables: &mut Tables, - dst_face: &mut Arc, + dst_face: &mut Face, res: &Arc, - src_face: &Option<&mut Arc>, + src_face: &Option<&Face>, send_declare: &mut SendDeclare, ) { - let info = local_qabl_info(tables, res, dst_face); - let current = face_hat!(dst_face).local_qabls.get(res); + let info = local_qabl_info(tables, res, &dst_face.state); + let current = face_hat!(dst_face.state).local_qabls.get(res); if src_face .as_ref() - .map(|src_face| dst_face.id != src_face.id) + .map(|src_face| dst_face.state.id != src_face.state.id) .unwrap_or(true) && (current.is_none() || current.unwrap().1 != info) - && (dst_face.whatami != WhatAmI::Client - || face_hat!(dst_face) + && (dst_face.state.whatami != WhatAmI::Client + || face_hat!(dst_face.state) .remote_interests .values() .any(|i| i.options.queryables() && i.matches(res))) && src_face .as_ref() .map(|src_face| { - src_face.whatami == WhatAmI::Client || dst_face.whatami == WhatAmI::Client + src_face.state.whatami == WhatAmI::Client + || dst_face.state.whatami == WhatAmI::Client }) .unwrap_or(true) { - let id = current - .map(|c| c.0) - .unwrap_or(face_hat!(dst_face).next_id.fetch_add(1, Ordering::SeqCst)); - face_hat_mut!(dst_face) + let id = current.map(|c| c.0).unwrap_or( + face_hat!(dst_face.state) + .next_id + .fetch_add(1, Ordering::SeqCst), + ); + face_hat_mut!(&mut dst_face.state) .local_qabls .insert(res.clone(), (id, info)); - let key_expr = Resource::decl_key(res, dst_face, super::push_declaration_profile(dst_face)); + let key_expr = Resource::decl_key( + res, + dst_face, + super::push_declaration_profile(&dst_face.state), + ); send_declare( - &dst_face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareQueryable(DeclareQueryable { - id, - wire_expr: key_expr, - ext_info: info, - }), - }, - res.expr().to_string(), - ), + dst_face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareQueryable(DeclareQueryable { + id, + wire_expr: key_expr, + ext_info: info, + }), + }, + Some(res.clone()), ); } } @@ -139,22 +144,17 @@ fn propagate_simple_queryable_to( fn propagate_simple_queryable( tables: &mut Tables, res: &Arc, - src_face: Option<&mut Arc>, + src_face: Option<&Face>, send_declare: &mut SendDeclare, ) { - let faces = tables - .faces - .values() - .cloned() - .collect::>>(); - for mut dst_face in faces { + for mut dst_face in tables.faces.values().cloned().collect::>() { propagate_simple_queryable_to(tables, &mut dst_face, res, &src_face, send_declare); } } fn register_simple_queryable( _tables: &mut Tables, - face: &mut Arc, + face: &Face, id: QueryableId, res: &mut Arc, qabl_info: &QueryableInfoType, @@ -164,17 +164,19 @@ fn register_simple_queryable( let res = get_mut_unchecked(res); get_mut_unchecked( res.session_ctxs - .entry(face.id) + .entry(face.state.id) .or_insert_with(|| Arc::new(SessionContext::new(face.clone()))), ) .qabl = Some(*qabl_info); } - face_hat_mut!(face).remote_qabls.insert(id, res.clone()); + face_hat_mut!(&mut face.state.clone()) + .remote_qabls + .insert(id, res.clone()); } fn declare_simple_queryable( tables: &mut Tables, - face: &mut Arc, + face: &Face, id: QueryableId, res: &mut Arc, qabl_info: &QueryableInfoType, @@ -185,7 +187,7 @@ fn declare_simple_queryable( } #[inline] -fn simple_qabls(res: &Arc) -> Vec> { +fn simple_qabls(res: &Arc) -> Vec { res.session_ctxs .values() .filter_map(|ctx| { @@ -202,7 +204,7 @@ fn simple_qabls(res: &Arc) -> Vec> { fn remote_simple_qabls(res: &Arc, face: &Arc) -> bool { res.session_ctxs .values() - .any(|ctx| ctx.face.id != face.id && ctx.qabl.is_some()) + .any(|ctx| ctx.face.state.id != face.id && ctx.qabl.is_some()) } fn propagate_forget_simple_queryable( @@ -211,25 +213,23 @@ fn propagate_forget_simple_queryable( send_declare: &mut SendDeclare, ) { for face in tables.faces.values_mut() { - if let Some((id, _)) = face_hat_mut!(face).local_qabls.remove(res) { + if let Some((id, _)) = face_hat_mut!(&mut face.state).local_qabls.remove(res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareQueryable(UndeclareQueryable { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareQueryable(UndeclareQueryable { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } - for res in face_hat!(face) + for res in face_hat!(face.state) .local_qabls .keys() .cloned() @@ -237,24 +237,22 @@ fn propagate_forget_simple_queryable( { if !res.context().matches.iter().any(|m| { m.upgrade() - .is_some_and(|m| m.context.is_some() && remote_simple_qabls(&m, face)) + .is_some_and(|m| m.context.is_some() && remote_simple_qabls(&m, &face.state)) }) { - if let Some((id, _)) = face_hat_mut!(face).local_qabls.remove(&res) { + if let Some((id, _)) = face_hat_mut!(&mut face.state).local_qabls.remove(&res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareQueryable(UndeclareQueryable { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareQueryable(UndeclareQueryable { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res), ); } } @@ -284,51 +282,48 @@ pub(super) fn undeclare_simple_queryable( propagate_simple_queryable(tables, res, None, send_declare); } if simple_qabls.len() == 1 { - let mut face = &mut simple_qabls[0]; - if let Some((id, _)) = face_hat_mut!(face).local_qabls.remove(res) { + let face = &mut simple_qabls[0]; + if let Some((id, _)) = face_hat_mut!(&mut face.state).local_qabls.remove(res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareQueryable(UndeclareQueryable { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareQueryable(UndeclareQueryable { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } - for res in face_hat!(face) + for res in face_hat!(face.state) .local_qabls .keys() .cloned() .collect::>>() { if !res.context().matches.iter().any(|m| { - m.upgrade() - .is_some_and(|m| m.context.is_some() && (remote_simple_qabls(&m, face))) + m.upgrade().is_some_and(|m| { + m.context.is_some() && (remote_simple_qabls(&m, &face.state)) + }) }) { - if let Some((id, _)) = face_hat_mut!(&mut face).local_qabls.remove(&res) { + if let Some((id, _)) = face_hat_mut!(&mut face.state).local_qabls.remove(&res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareQueryable(UndeclareQueryable { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareQueryable(UndeclareQueryable { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res), ); } } @@ -353,24 +348,13 @@ fn forget_simple_queryable( pub(super) fn queries_new_face( tables: &mut Tables, - face: &mut Arc, + face: &mut Face, send_declare: &mut SendDeclare, ) { - if face.whatami != WhatAmI::Client { - for src_face in tables - .faces - .values() - .cloned() - .collect::>>() - { - for qabl in face_hat!(src_face).remote_qabls.values() { - propagate_simple_queryable_to( - tables, - face, - qabl, - &Some(&mut src_face.clone()), - send_declare, - ); + if face.state.whatami != WhatAmI::Client { + for src_face in tables.faces.values().cloned().collect::>() { + for qabl in face_hat!(src_face.state).remote_qabls.values() { + propagate_simple_queryable_to(tables, face, qabl, &Some(&src_face), send_declare); } } } @@ -404,79 +388,70 @@ fn make_qabl_id( pub(super) fn declare_qabl_interest( tables: &mut Tables, - face: &mut Arc, + face: &Face, id: InterestId, res: Option<&mut Arc>, mode: InterestMode, aggregate: bool, send_declare: &mut SendDeclare, ) { - if mode.current() && face.whatami == WhatAmI::Client { + if mode.current() && face.state.whatami == WhatAmI::Client { let interest_id = Some(id); if let Some(res) = res.as_ref() { if aggregate { if tables.faces.values().any(|src_face| { - src_face.id != face.id - && face_hat!(src_face) + src_face.state.id != face.state.id + && face_hat!(src_face.state) .remote_qabls .values() .any(|qabl| qabl.context.is_some() && qabl.matches(res)) }) { - let info = local_qabl_info(tables, res, face); - let id = make_qabl_id(res, face, mode, info); + let info = local_qabl_info(tables, res, &face.state); + let id = make_qabl_id(res, &mut face.state.clone(), mode, info); let wire_expr = - Resource::decl_key(res, face, super::push_declaration_profile(face)); + Resource::decl_key(res, face, super::push_declaration_profile(&face.state)); send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareQueryable(DeclareQueryable { - id, - wire_expr, - ext_info: info, - }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareQueryable(DeclareQueryable { + id, + wire_expr, + ext_info: info, + }), + }, + Some(res.deref().clone()), ); } } else { - for src_face in tables - .faces - .values() - .cloned() - .collect::>>() - { - if src_face.id != face.id { - for qabl in face_hat!(src_face).remote_qabls.values() { + for src_face in tables.faces.values().cloned().collect::>() { + if src_face.state.id != face.state.id { + for qabl in face_hat!(src_face.state).remote_qabls.values() { if qabl.context.is_some() && qabl.matches(res) { - let info = local_qabl_info(tables, qabl, face); - let id = make_qabl_id(qabl, face, mode, info); + let info = local_qabl_info(tables, qabl, &face.state); + let id = make_qabl_id(qabl, &mut face.state.clone(), mode, info); let key_expr = Resource::decl_key( qabl, face, - super::push_declaration_profile(face), + super::push_declaration_profile(&face.state), ); send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareQueryable(DeclareQueryable { - id, - wire_expr: key_expr, - ext_info: info, - }), - }, - qabl.expr().to_string(), - ), + face, + Declare { + interest_id, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareQueryable(DeclareQueryable { + id, + wire_expr: key_expr, + ext_info: info, + }), + }, + Some(qabl.clone()), ); } } @@ -484,38 +459,31 @@ pub(super) fn declare_qabl_interest( } } } else { - for src_face in tables - .faces - .values() - .cloned() - .collect::>>() - { - if src_face.id != face.id { - for qabl in face_hat!(src_face).remote_qabls.values() { + for src_face in tables.faces.values().cloned().collect::>() { + if src_face.state.id != face.state.id { + for qabl in face_hat!(src_face.state).remote_qabls.values() { if qabl.context.is_some() { - let info = local_qabl_info(tables, qabl, face); - let id = make_qabl_id(qabl, face, mode, info); + let info = local_qabl_info(tables, qabl, &face.state); + let id = make_qabl_id(qabl, &mut face.state.clone(), mode, info); let key_expr = Resource::decl_key( qabl, face, - super::push_declaration_profile(face), + super::push_declaration_profile(&face.state), ); send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareQueryable(DeclareQueryable { - id, - wire_expr: key_expr, - ext_info: info, - }), - }, - qabl.expr().to_string(), - ), + face, + Declare { + interest_id, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareQueryable(DeclareQueryable { + id, + wire_expr: key_expr, + ext_info: info, + }), + }, + Some(qabl.clone()), ); } } @@ -529,7 +497,7 @@ impl HatQueriesTrait for HatCode { fn declare_queryable( &self, tables: &mut Tables, - face: &mut Arc, + face: &Face, id: QueryableId, res: &mut Arc, qabl_info: &QueryableInfoType, @@ -555,14 +523,14 @@ impl HatQueriesTrait for HatCode { // Compute the list of known queryables (keys) let mut qabls = HashMap::new(); for src_face in tables.faces.values() { - for qabl in face_hat!(src_face).remote_qabls.values() { + for qabl in face_hat!(src_face.state).remote_qabls.values() { // Insert the key in the list of known queryables let srcs = qabls.entry(qabl.clone()).or_insert_with(Sources::empty); // Append src_face as a queryable source in the proper list - match src_face.whatami { - WhatAmI::Router => srcs.routers.push(src_face.zid), - WhatAmI::Peer => srcs.peers.push(src_face.zid), - WhatAmI::Client => srcs.clients.push(src_face.zid), + match src_face.state.whatami { + WhatAmI::Router => srcs.routers.push(src_face.state.zid), + WhatAmI::Peer => srcs.peers.push(src_face.state.zid), + WhatAmI::Client => srcs.clients.push(src_face.state.zid), } } } @@ -572,14 +540,14 @@ impl HatQueriesTrait for HatCode { fn get_queriers(&self, tables: &Tables) -> Vec<(Arc, Sources)> { let mut result = HashMap::new(); for face in tables.faces.values() { - for interest in face_hat!(face).remote_interests.values() { + for interest in face_hat!(face.state).remote_interests.values() { if interest.options.queryables() { if let Some(res) = interest.res.as_ref() { let sources = result.entry(res.clone()).or_insert_with(Sources::default); - match face.whatami { - WhatAmI::Router => sources.routers.push(face.zid), - WhatAmI::Peer => sources.peers.push(face.zid), - WhatAmI::Client => sources.clients.push(face.zid), + match face.state.whatami { + WhatAmI::Router => sources.routers.push(face.state.zid), + WhatAmI::Peer => sources.peers.push(face.state.zid), + WhatAmI::Client => sources.clients.push(face.state.zid), } } } @@ -619,9 +587,9 @@ impl HatQueriesTrait for HatCode { for face in tables .faces .values() - .filter(|f| f.whatami == WhatAmI::Router) + .filter(|f| f.state.whatami == WhatAmI::Router) { - if !face.local_interests.values().any(|interest| { + if !face.state.local_interests.values().any(|interest| { interest.finalized && interest.options.queryables() && interest @@ -629,12 +597,12 @@ impl HatQueriesTrait for HatCode { .as_ref() .map(|res| KeyExpr::keyexpr_include(res.expr(), expr.full_expr())) .unwrap_or(true) - }) || face_hat!(face) + }) || face_hat!(face.state) .remote_qabls .values() .any(|sub| KeyExpr::keyexpr_intersect(sub.expr(), expr.full_expr())) { - let key_expr = Resource::get_best_key(expr.prefix, expr.suffix, face.id); + let key_expr = Resource::get_best_key(expr.prefix, expr.suffix, face.state.id); route.push(QueryTargetQabl { direction: (face.clone(), key_expr.to_owned(), NodeId::default()), info: None, @@ -643,10 +611,12 @@ impl HatQueriesTrait for HatCode { } for face in tables.faces.values().filter(|f| { - f.whatami == WhatAmI::Peer - && !initial_interest(f).map(|i| i.finalized).unwrap_or(true) + f.state.whatami == WhatAmI::Peer + && !initial_interest(&f.state) + .map(|i| i.finalized) + .unwrap_or(true) }) { - let key_expr = Resource::get_best_key(expr.prefix, expr.suffix, face.id); + let key_expr = Resource::get_best_key(expr.prefix, expr.suffix, face.state.id); route.push(QueryTargetQabl { direction: (face.clone(), key_expr.to_owned(), NodeId::default()), info: None, @@ -665,7 +635,7 @@ impl HatQueriesTrait for HatCode { let mres = mres.upgrade().unwrap(); let complete = DEFAULT_INCLUDER.includes(mres.expr().as_bytes(), key_expr.as_bytes()); for (sid, context) in &mres.session_ctxs { - if source_type == WhatAmI::Client || context.face.whatami == WhatAmI::Client { + if source_type == WhatAmI::Client || context.face.state.whatami == WhatAmI::Client { let key_expr = Resource::get_best_key(expr.prefix, expr.suffix, *sid); if let Some(qabl_info) = context.qabl.as_ref() { route.push(QueryTargetQabl { @@ -722,7 +692,7 @@ impl HatQueriesTrait for HatCode { } { matching_queryables .entry(*sid) - .or_insert_with(|| context.face.clone()); + .or_insert_with(|| context.face.state.clone()); } } } diff --git a/zenoh/src/net/routing/hat/p2p_peer/token.rs b/zenoh/src/net/routing/hat/p2p_peer/token.rs index d4dd1cfdc4..b9ce2fc66e 100644 --- a/zenoh/src/net/routing/hat/p2p_peer/token.rs +++ b/zenoh/src/net/routing/hat/p2p_peer/token.rs @@ -12,7 +12,10 @@ // ZettaScale Zenoh Team, // -use std::sync::{atomic::Ordering, Arc}; +use std::{ + ops::Deref, + sync::{atomic::Ordering, Arc}, +}; use zenoh_config::WhatAmI; use zenoh_protocol::network::{ @@ -25,10 +28,13 @@ use zenoh_sync::get_mut_unchecked; use super::{face_hat, face_hat_mut, HatCode, HatFace, INITIAL_INTEREST_ID}; use crate::net::routing::{ - dispatcher::{face::FaceState, interests::RemoteInterest, tables::Tables}, + dispatcher::{ + face::{Face, FaceState}, + interests::RemoteInterest, + tables::Tables, + }, hat::{CurrentFutureTrait, HatTokenTrait, SendDeclare}, router::{NodeId, Resource, SessionContext}, - RoutingContext, }; fn new_token( @@ -40,9 +46,9 @@ fn new_token( // Is there any face that !res.session_ctxs.values().any(|ctx| { ctx.token // declared the token - && (ctx.face.id != src_face.id) // is not the face that just registered it - && (ctx.face.id != dst_face.id || dst_face.zid == tables.zid) // is not the face we are propagating to (except for local) - && (ctx.face.whatami == WhatAmI::Client || dst_face.whatami == WhatAmI::Client) + && (ctx.face.state.id != src_face.id) // is not the face that just registered it + && (ctx.face.state.id != dst_face.id || dst_face.zid == tables.zid) // is not the face we are propagating to (except for local) + && (ctx.face.state.whatami == WhatAmI::Client || dst_face.whatami == WhatAmI::Client) // don't forward from/to router/peers }) } @@ -50,41 +56,46 @@ fn new_token( #[inline] fn propagate_simple_token_to( tables: &mut Tables, - dst_face: &mut Arc, + dst_face: &mut Face, res: &Arc, src_face: &mut Arc, src_interest_id: Option, dst_interest_id: Option, send_declare: &mut SendDeclare, ) { - if (src_face.id != dst_face.id || dst_face.zid == tables.zid) - && !face_hat!(dst_face).local_tokens.contains_key(res) - && (src_face.whatami == WhatAmI::Client || dst_face.whatami == WhatAmI::Client) - && new_token(tables, res, src_face, dst_face) + if (src_face.id != dst_face.state.id || dst_face.state.zid == tables.zid) + && !face_hat!(dst_face.state).local_tokens.contains_key(res) + && (src_face.whatami == WhatAmI::Client || dst_face.state.whatami == WhatAmI::Client) + && new_token(tables, res, src_face, &mut dst_face.state) { - if dst_face.whatami != WhatAmI::Client { - let id = face_hat!(dst_face).next_id.fetch_add(1, Ordering::SeqCst); - face_hat_mut!(dst_face).local_tokens.insert(res.clone(), id); - let key_expr = - Resource::decl_key(res, dst_face, super::push_declaration_profile(dst_face)); + if dst_face.state.whatami != WhatAmI::Client { + let id = face_hat!(dst_face.state) + .next_id + .fetch_add(1, Ordering::SeqCst); + face_hat_mut!(&mut dst_face.state) + .local_tokens + .insert(res.clone(), id); + let key_expr = Resource::decl_key( + res, + dst_face, + super::push_declaration_profile(&dst_face.state), + ); send_declare( - &dst_face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: dst_interest_id, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareToken(DeclareToken { - id, - wire_expr: key_expr, - }), - }, - res.expr().to_string(), - ), + dst_face, + Declare { + interest_id: dst_interest_id, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareToken(DeclareToken { + id, + wire_expr: key_expr, + }), + }, + Some(res.clone()), ); } else { - let matching_interests = face_hat!(dst_face) + let matching_interests = face_hat!(dst_face.state) .remote_interests .values() .filter(|i| { @@ -106,29 +117,31 @@ fn propagate_simple_token_to( } else { res }; - if !face_hat!(dst_face).local_tokens.contains_key(res) { - let id = face_hat!(dst_face).next_id.fetch_add(1, Ordering::SeqCst); - face_hat_mut!(dst_face).local_tokens.insert(res.clone(), id); + if !face_hat!(dst_face.state).local_tokens.contains_key(res) { + let id = face_hat!(dst_face.state) + .next_id + .fetch_add(1, Ordering::SeqCst); + face_hat_mut!(&mut dst_face.state) + .local_tokens + .insert(res.clone(), id); let key_expr = Resource::decl_key( res, dst_face, - super::push_declaration_profile(dst_face), + super::push_declaration_profile(&dst_face.state), ); send_declare( - &dst_face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: dst_interest_id, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareToken(DeclareToken { - id, - wire_expr: key_expr, - }), - }, - res.expr().to_string(), - ), + dst_face, + Declare { + interest_id: dst_interest_id, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareToken(DeclareToken { + id, + wire_expr: key_expr, + }), + }, + Some(res.clone()), ); } } @@ -143,12 +156,7 @@ fn propagate_simple_token( interest_id: Option, send_declare: &mut SendDeclare, ) { - for mut dst_face in tables - .faces - .values() - .cloned() - .collect::>>() - { + for mut dst_face in tables.faces.values().cloned().collect::>() { propagate_simple_token_to( tables, &mut dst_face, @@ -161,16 +169,11 @@ fn propagate_simple_token( } } -fn register_simple_token( - _tables: &mut Tables, - face: &mut Arc, - id: TokenId, - res: &mut Arc, -) { +fn register_simple_token(_tables: &mut Tables, face: &Face, id: TokenId, res: &mut Arc) { // Register liveliness { let res = get_mut_unchecked(res); - match res.session_ctxs.get_mut(&face.id) { + match res.session_ctxs.get_mut(&face.state.id) { Some(ctx) => { if !ctx.token { get_mut_unchecked(ctx).token = true; @@ -179,18 +182,20 @@ fn register_simple_token( None => { let ctx = res .session_ctxs - .entry(face.id) + .entry(face.state.id) .or_insert_with(|| Arc::new(SessionContext::new(face.clone()))); get_mut_unchecked(ctx).token = true; } } } - face_hat_mut!(face).remote_tokens.insert(id, res.clone()); + face_hat_mut!(&mut face.state.clone()) + .remote_tokens + .insert(id, res.clone()); } fn declare_simple_token( tables: &mut Tables, - face: &mut Arc, + face: &Face, id: TokenId, res: &mut Arc, interest_id: Option, @@ -198,30 +203,29 @@ fn declare_simple_token( ) { if let Some(interest_id) = interest_id { if let Some(interest) = face + .state .pending_current_interests .get(&interest_id) .map(|p| &p.interest) { if interest.mode == InterestMode::CurrentFuture { - register_simple_token(tables, &mut face.clone(), id, res); + register_simple_token(tables, face, id, res); } - let id = make_token_id(res, &mut interest.src_face.clone(), interest.mode); - let wire_expr = Resource::get_best_key(res, "", interest.src_face.id); + let id = make_token_id(res, &mut interest.src_face.state.clone(), interest.mode); + let wire_expr = Resource::get_best_key(res, "", interest.src_face.state.id); send_declare( - &interest.src_face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: Some(interest.src_interest_id), - ext_qos: ext::QoSType::default(), - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::default(), - body: DeclareBody::DeclareToken(DeclareToken { id, wire_expr }), - }, - res.expr().to_string(), - ), + &interest.src_face, + Declare { + interest_id: Some(interest.src_interest_id), + ext_qos: ext::QoSType::default(), + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::DeclareToken(DeclareToken { id, wire_expr }), + }, + Some(res.clone()), ); return; - } else if !face.local_interests.contains_key(&interest_id) { + } else if !face.state.local_interests.contains_key(&interest_id) { println!( "Received DeclareToken for {} from {} with unknown interest_id {}. Ignore.", res.expr(), @@ -232,11 +236,17 @@ fn declare_simple_token( } } register_simple_token(tables, face, id, res); - propagate_simple_token(tables, res, face, interest_id, send_declare); + propagate_simple_token( + tables, + res, + &mut face.state.clone(), + interest_id, + send_declare, + ); } #[inline] -fn simple_tokens(res: &Arc) -> Vec> { +fn simple_tokens(res: &Arc) -> Vec { res.session_ctxs .values() .filter_map(|ctx| { @@ -253,7 +263,7 @@ fn simple_tokens(res: &Arc) -> Vec> { fn remote_simple_tokens(tables: &Tables, res: &Arc, face: &Arc) -> bool { res.session_ctxs .values() - .any(|ctx| (ctx.face.id != face.id || face.zid == tables.zid) && ctx.token) + .any(|ctx| (ctx.face.state.id != face.id || face.zid == tables.zid) && ctx.token) } fn propagate_forget_simple_token( @@ -263,25 +273,23 @@ fn propagate_forget_simple_token( send_declare: &mut SendDeclare, ) { for mut face in tables.faces.values().cloned() { - if let Some(id) = face_hat_mut!(&mut face).local_tokens.remove(res) { + if let Some(id) = face_hat_mut!(&mut face.state).local_tokens.remove(res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareToken(UndeclareToken { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + &face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareToken(UndeclareToken { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); - } else if src_face.id != face.id - && face_hat!(face) + } else if src_face.id != face.state.id + && face_hat!(face.state) .remote_interests .values() .any(|i| i.options.tokens() && i.matches(res) && !i.options.aggregate()) @@ -289,52 +297,49 @@ fn propagate_forget_simple_token( // Token has never been declared on this face. // Send an Undeclare with a one shot generated id and a WireExpr ext. send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareToken(UndeclareToken { - id: face_hat!(face).next_id.fetch_add(1, Ordering::SeqCst), - ext_wire_expr: WireExprType { - wire_expr: Resource::get_best_key(res, "", face.id), - }, - }), - }, - res.expr().to_string(), - ), + &face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareToken(UndeclareToken { + id: face_hat!(face.state).next_id.fetch_add(1, Ordering::SeqCst), + ext_wire_expr: WireExprType { + wire_expr: Resource::get_best_key(res, "", face.state.id), + }, + }), + }, + Some(res.clone()), ); } - for res in face_hat!(face) + for res in face_hat!(face.state) .local_tokens .keys() .cloned() .collect::>>() { if !res.context().matches.iter().any(|m| { - m.upgrade() - .is_some_and(|m| m.context.is_some() && remote_simple_tokens(tables, &m, &face)) + m.upgrade().is_some_and(|m| { + m.context.is_some() && remote_simple_tokens(tables, &m, &face.state) + }) }) { - if let Some(id) = face_hat_mut!(&mut face).local_tokens.remove(&res) { + if let Some(id) = face_hat_mut!(&mut face.state).local_tokens.remove(&res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareToken(UndeclareToken { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + &face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareToken(UndeclareToken { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); - } else if face_hat!(face) + } else if face_hat!(face.state) .remote_interests .values() .any(|i| i.options.tokens() && i.matches(&res) && !i.options.aggregate()) @@ -342,22 +347,20 @@ fn propagate_forget_simple_token( // Token has never been declared on this face. // Send an Undeclare with a one shot generated id and a WireExpr ext. send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareToken(UndeclareToken { - id: face_hat!(face).next_id.fetch_add(1, Ordering::SeqCst), - ext_wire_expr: WireExprType { - wire_expr: Resource::get_best_key(&res, "", face.id), - }, - }), - }, - res.expr().to_string(), - ), + &face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareToken(UndeclareToken { + id: face_hat!(face.state).next_id.fetch_add(1, Ordering::SeqCst), + ext_wire_expr: WireExprType { + wire_expr: Resource::get_best_key(&res, "", face.state.id), + }, + }), + }, + Some(res.clone()), ); } } @@ -386,27 +389,25 @@ pub(super) fn undeclare_simple_token( } if simple_tokens.len() == 1 { - let mut face = &mut simple_tokens[0]; - if face.whatami != WhatAmI::Client { - if let Some(id) = face_hat_mut!(face).local_tokens.remove(res) { + let face = &mut simple_tokens[0]; + if face.state.whatami != WhatAmI::Client { + if let Some(id) = face_hat_mut!(&mut face.state).local_tokens.remove(res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareToken(UndeclareToken { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareToken(UndeclareToken { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } - for res in face_hat!(face) + for res in face_hat!(face.state) .local_tokens .keys() .cloned() @@ -414,25 +415,23 @@ pub(super) fn undeclare_simple_token( { if !res.context().matches.iter().any(|m| { m.upgrade().is_some_and(|m| { - m.context.is_some() && remote_simple_tokens(tables, &m, face) + m.context.is_some() && remote_simple_tokens(tables, &m, &face.state) }) }) { - if let Some(id) = face_hat_mut!(&mut face).local_tokens.remove(&res) { + if let Some(id) = face_hat_mut!(&mut face.state).local_tokens.remove(&res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareToken(UndeclareToken { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareToken(UndeclareToken { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } } @@ -460,24 +459,15 @@ fn forget_simple_token( } } -pub(super) fn token_new_face( - tables: &mut Tables, - face: &mut Arc, - send_declare: &mut SendDeclare, -) { - if face.whatami != WhatAmI::Client { - for mut src_face in tables - .faces - .values() - .cloned() - .collect::>>() - { - for token in face_hat!(src_face.clone()).remote_tokens.values() { +pub(super) fn token_new_face(tables: &mut Tables, face: &mut Face, send_declare: &mut SendDeclare) { + if face.state.whatami != WhatAmI::Client { + for mut src_face in tables.faces.values().cloned().collect::>() { + for token in face_hat!(src_face.state.clone()).remote_tokens.values() { propagate_simple_token_to( tables, face, token, - &mut src_face, + &mut src_face.state, None, Some(INITIAL_INTEREST_ID), send_declare, @@ -504,7 +494,7 @@ fn make_token_id(res: &Arc, face: &mut Arc, mode: InterestM pub(crate) fn declare_token_interest( tables: &mut Tables, - face: &mut Arc, + face: &Face, id: InterestId, res: Option<&mut Arc>, mode: InterestMode, @@ -516,59 +506,52 @@ pub(crate) fn declare_token_interest( if let Some(res) = res.as_ref() { if aggregate { if tables.faces.values().any(|src_face| { - face_hat!(src_face) + face_hat!(src_face.state) .remote_tokens .values() .any(|token| token.context.is_some() && token.matches(res)) }) { - let id = make_token_id(res, face, mode); + let id = make_token_id(res, &mut face.state.clone(), mode); let wire_expr = - Resource::decl_key(res, face, super::push_declaration_profile(face)); + Resource::decl_key(res, face, super::push_declaration_profile(&face.state)); send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareToken(DeclareToken { id, wire_expr }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareToken(DeclareToken { id, wire_expr }), + }, + Some(res.deref().clone()), ); } } else { for src_face in tables .faces .values() - .filter(|f| f.whatami != WhatAmI::Router) + .filter(|f| f.state.whatami != WhatAmI::Router) .cloned() - .collect::>>() + .collect::>() { - for token in face_hat!(src_face).remote_tokens.values() { + for token in face_hat!(src_face.state).remote_tokens.values() { if token.context.is_some() && token.matches(res) { - let id = make_token_id(token, face, mode); + let id = make_token_id(token, &mut face.state.clone(), mode); let wire_expr = Resource::decl_key( token, face, - super::push_declaration_profile(face), + super::push_declaration_profile(&face.state), ); send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareToken(DeclareToken { - id, - wire_expr, - }), - }, - token.expr().to_string(), - ), + face, + Declare { + interest_id, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareToken(DeclareToken { id, wire_expr }), + }, + Some(token.clone()), ); } } @@ -578,26 +561,27 @@ pub(crate) fn declare_token_interest( for src_face in tables .faces .values() - .filter(|f| f.whatami != WhatAmI::Router) + .filter(|f| f.state.whatami != WhatAmI::Router) .cloned() - .collect::>>() + .collect::>() { - for token in face_hat!(src_face).remote_tokens.values() { - let id = make_token_id(token, face, mode); - let wire_expr = - Resource::decl_key(token, face, super::push_declaration_profile(face)); + for token in face_hat!(src_face.state).remote_tokens.values() { + let id = make_token_id(token, &mut face.state.clone(), mode); + let wire_expr = Resource::decl_key( + token, + face, + super::push_declaration_profile(&face.state), + ); send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareToken(DeclareToken { id, wire_expr }), - }, - token.expr().to_string(), - ), + face, + Declare { + interest_id, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareToken(DeclareToken { id, wire_expr }), + }, + Some(token.clone()), ); } } @@ -609,7 +593,7 @@ impl HatTokenTrait for HatCode { fn declare_token( &self, tables: &mut Tables, - face: &mut Arc, + face: &Face, id: TokenId, res: &mut Arc, _node_id: NodeId, diff --git a/zenoh/src/net/routing/hat/router/interests.rs b/zenoh/src/net/routing/hat/router/interests.rs index 4e8ee3c7f3..84f1707b6c 100644 --- a/zenoh/src/net/routing/hat/router/interests.rs +++ b/zenoh/src/net/routing/hat/router/interests.rs @@ -29,13 +29,12 @@ use super::{ }; use crate::net::routing::{ dispatcher::{ - face::FaceState, + face::{Face, FaceState}, interests::RemoteInterest, resource::Resource, tables::{Tables, TablesLock}, }, hat::{CurrentFutureTrait, HatInterestTrait, SendDeclare}, - RoutingContext, }; impl HatInterestTrait for HatCode { @@ -43,17 +42,17 @@ impl HatInterestTrait for HatCode { &self, tables: &mut Tables, _tables_ref: &Arc, - face: &mut Arc, + face: &Face, id: InterestId, res: Option<&mut Arc>, mode: InterestMode, mut options: InterestOptions, send_declare: &mut SendDeclare, ) { - if options.aggregate() && face.whatami == WhatAmI::Peer { + if options.aggregate() && face.state.whatami == WhatAmI::Peer { tracing::warn!( "Received Interest with aggregate=true from peer {}. Not supported!", - face.zid + face.state.zid ); options -= InterestOptions::AGGREGATE; } @@ -91,25 +90,28 @@ impl HatInterestTrait for HatCode { ) } if mode.future() { - face_hat_mut!(face).remote_interests.insert( - id, - RemoteInterest { - res: res.cloned(), - options, - mode, - }, - ); + face_hat_mut!(&mut face.state.clone()) + .remote_interests + .insert( + id, + RemoteInterest { + res: res.cloned(), + options, + mode, + }, + ); } if mode.current() { send_declare( - &face.primitives, - RoutingContext::new(Declare { + face, + Declare { interest_id: Some(id), ext_qos: ext::QoSType::DECLARE, ext_tstamp: None, ext_nodeid: ext::NodeIdType::DEFAULT, body: DeclareBody::DeclareFinal(DeclareFinal), - }), + }, + None, ); } } diff --git a/zenoh/src/net/routing/hat/router/pubsub.rs b/zenoh/src/net/routing/hat/router/pubsub.rs index d6da037c5c..77688b9d1a 100644 --- a/zenoh/src/net/routing/hat/router/pubsub.rs +++ b/zenoh/src/net/routing/hat/router/pubsub.rs @@ -14,6 +14,7 @@ use std::{ borrow::Cow, collections::{HashMap, HashSet}, + ops::Deref, sync::{atomic::Ordering, Arc}, }; @@ -38,7 +39,7 @@ use super::{ use crate::key_expr::KeyExpr; use crate::net::routing::{ dispatcher::{ - face::FaceState, + face::{Face, FaceState}, interests::RemoteInterest, pubsub::SubscriberInfo, resource::{NodeId, Resource, SessionContext}, @@ -46,7 +47,6 @@ use crate::net::routing::{ }, hat::{CurrentFutureTrait, HatPubSubTrait, SendDeclare, Sources}, router::disable_matches_data_routes, - RoutingContext, }; #[inline] @@ -62,15 +62,15 @@ fn send_sourced_subscription_to_net_children( for child in children { if net.graph.contains_node(*child) { match tables.get_face(&net.graph[*child].zid).cloned() { - Some(mut someface) => { + Some(someface) => { if src_face - .map(|src_face| someface.id != src_face.id) + .map(|src_face| someface.state.id != src_face.id) .unwrap_or(true) { - let push_declaration = push_declaration_profile(tables, &someface); - let key_expr = Resource::decl_key(res, &mut someface, push_declaration); + let push_declaration = push_declaration_profile(tables, &someface.state); + let key_expr = Resource::decl_key(res, &someface, push_declaration); - someface.primitives.send_declare(RoutingContext::with_expr( + someface.intercept_declare( &mut Declare { interest_id: None, ext_qos: ext::QoSType::DECLARE, @@ -83,8 +83,8 @@ fn send_sourced_subscription_to_net_children( wire_expr: key_expr, }), }, - res.expr().to_string(), - )); + Some(res), + ); } } None => tracing::trace!("Unable to find face for zid {}", net.graph[*child].zid), @@ -96,25 +96,25 @@ fn send_sourced_subscription_to_net_children( #[inline] fn propagate_simple_subscription_to( tables: &mut Tables, - dst_face: &mut Arc, + dst_face: &mut Face, res: &Arc, _sub_info: &SubscriberInfo, src_face: &mut Arc, full_peer_net: bool, send_declare: &mut SendDeclare, ) { - if src_face.id != dst_face.id - && !face_hat!(dst_face).local_subs.contains_key(res) + if src_face.id != dst_face.state.id + && !face_hat!(dst_face.state).local_subs.contains_key(res) && if full_peer_net { - dst_face.whatami == WhatAmI::Client + dst_face.state.whatami == WhatAmI::Client } else { - dst_face.whatami != WhatAmI::Router + dst_face.state.whatami != WhatAmI::Router && (src_face.whatami != WhatAmI::Peer - || dst_face.whatami != WhatAmI::Peer - || hat!(tables).failover_brokering(src_face.zid, dst_face.zid)) + || dst_face.state.whatami != WhatAmI::Peer + || hat!(tables).failover_brokering(src_face.zid, dst_face.state.zid)) } { - let matching_interests = face_hat!(dst_face) + let matching_interests = face_hat!(dst_face.state) .remote_interests .values() .filter(|i| i.options.subscribers() && i.matches(res)) @@ -132,26 +132,31 @@ fn propagate_simple_subscription_to( } else { res }; - if !face_hat!(dst_face).local_subs.contains_key(res) { - let id = face_hat!(dst_face).next_id.fetch_add(1, Ordering::SeqCst); - face_hat_mut!(dst_face).local_subs.insert(res.clone(), id); - let key_expr = - Resource::decl_key(res, dst_face, push_declaration_profile(tables, dst_face)); + if !face_hat!(dst_face.state).local_subs.contains_key(res) { + let id = face_hat!(dst_face.state) + .next_id + .fetch_add(1, Ordering::SeqCst); + face_hat_mut!(&mut dst_face.state) + .local_subs + .insert(res.clone(), id); + let key_expr = Resource::decl_key( + res, + dst_face, + push_declaration_profile(tables, &dst_face.state), + ); send_declare( - &dst_face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareSubscriber(DeclareSubscriber { - id, - wire_expr: key_expr, - }), - }, - res.expr().to_string(), - ), + dst_face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareSubscriber(DeclareSubscriber { + id, + wire_expr: key_expr, + }), + }, + Some(res.clone()), ); } } @@ -166,12 +171,7 @@ fn propagate_simple_subscription( send_declare: &mut SendDeclare, ) { let full_peer_net = hat!(tables).full_net(WhatAmI::Peer); - for mut dst_face in tables - .faces - .values() - .cloned() - .collect::>>() - { + for mut dst_face in tables.faces.values().cloned().collect::>() { propagate_simple_subscription_to( tables, &mut dst_face, @@ -295,7 +295,7 @@ fn declare_linkstatepeer_subscription( fn register_simple_subscription( _tables: &mut Tables, - face: &mut Arc, + face: &Face, id: SubscriberId, res: &mut Arc, sub_info: &SubscriberInfo, @@ -303,7 +303,7 @@ fn register_simple_subscription( // Register subscription { let res = get_mut_unchecked(res); - match res.session_ctxs.get_mut(&face.id) { + match res.session_ctxs.get_mut(&face.state.id) { Some(ctx) => { if ctx.subs.is_none() { get_mut_unchecked(ctx).subs = Some(*sub_info); @@ -312,18 +312,20 @@ fn register_simple_subscription( None => { let ctx = res .session_ctxs - .entry(face.id) + .entry(face.state.id) .or_insert_with(|| Arc::new(SessionContext::new(face.clone()))); get_mut_unchecked(ctx).subs = Some(*sub_info); } } } - face_hat_mut!(face).remote_subs.insert(id, res.clone()); + face_hat_mut!(&mut face.state.clone()) + .remote_subs + .insert(id, res.clone()); } fn declare_simple_subscription( tables: &mut Tables, - face: &mut Arc, + face: &Face, id: SubscriberId, res: &mut Arc, sub_info: &SubscriberInfo, @@ -331,7 +333,14 @@ fn declare_simple_subscription( ) { register_simple_subscription(tables, face, id, res, sub_info); let zid = tables.zid; - register_router_subscription(tables, face, res, sub_info, zid, send_declare); + register_router_subscription( + tables, + &mut face.state.clone(), + res, + sub_info, + zid, + send_declare, + ); } #[inline] @@ -353,7 +362,7 @@ fn remote_linkstatepeer_subs(tables: &Tables, res: &Arc) -> bool { } #[inline] -fn simple_subs(res: &Arc) -> Vec> { +fn simple_subs(res: &Arc) -> Vec { res.session_ctxs .values() .filter_map(|ctx| { @@ -370,7 +379,7 @@ fn simple_subs(res: &Arc) -> Vec> { fn remote_simple_subs(res: &Arc, face: &Arc) -> bool { res.session_ctxs .values() - .any(|ctx| ctx.face.id != face.id && ctx.subs.is_some()) + .any(|ctx| ctx.face.state.id != face.id && ctx.subs.is_some()) } #[inline] @@ -385,15 +394,15 @@ fn send_forget_sourced_subscription_to_net_children( for child in children { if net.graph.contains_node(*child) { match tables.get_face(&net.graph[*child].zid).cloned() { - Some(mut someface) => { + Some(someface) => { if src_face - .map(|src_face| someface.id != src_face.id) + .map(|src_face| someface.state.id != src_face.id) .unwrap_or(true) { - let push_declaration = push_declaration_profile(tables, &someface); - let wire_expr = Resource::decl_key(res, &mut someface, push_declaration); + let push_declaration = push_declaration_profile(tables, &someface.state); + let wire_expr = Resource::decl_key(res, &someface, push_declaration); - someface.primitives.send_declare(RoutingContext::with_expr( + someface.intercept_declare( &mut Declare { interest_id: None, ext_qos: ext::QoSType::DECLARE, @@ -406,8 +415,8 @@ fn send_forget_sourced_subscription_to_net_children( ext_wire_expr: WireExprType { wire_expr }, }), }, - res.expr().to_string(), - )); + Some(res), + ); } } None => tracing::trace!("Unable to find face for zid {}", net.graph[*child].zid), @@ -422,25 +431,23 @@ fn propagate_forget_simple_subscription( send_declare: &mut SendDeclare, ) { for mut face in tables.faces.values().cloned() { - if let Some(id) = face_hat_mut!(&mut face).local_subs.remove(res) { + if let Some(id) = face_hat_mut!(&mut face.state).local_subs.remove(res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + &face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } - for res in face_hat!(&mut face) + for res in face_hat!(&mut face.state) .local_subs .keys() .cloned() @@ -449,27 +456,25 @@ fn propagate_forget_simple_subscription( if !res.context().matches.iter().any(|m| { m.upgrade().is_some_and(|m| { m.context.is_some() - && (remote_simple_subs(&m, &face) + && (remote_simple_subs(&m, &face.state) || remote_linkstatepeer_subs(tables, &m) || remote_router_subs(tables, &m)) }) }) { - if let Some(id) = face_hat_mut!(&mut face).local_subs.remove(&res) { + if let Some(id) = face_hat_mut!(&mut face.state).local_subs.remove(&res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + &face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } } @@ -486,38 +491,32 @@ fn propagate_forget_simple_subscription_to_peers( && res_hat!(res).router_subs.len() == 1 && res_hat!(res).router_subs.contains(&tables.zid) { - for mut face in tables - .faces - .values() - .cloned() - .collect::>>() - { - if face.whatami == WhatAmI::Peer - && face_hat!(face).local_subs.contains_key(res) + for mut face in tables.faces.values().cloned().collect::>() { + if face.state.whatami == WhatAmI::Peer + && face_hat!(face.state).local_subs.contains_key(res) && !res.session_ctxs.values().any(|s| { - face.zid != s.face.zid + face.state.zid != s.face.state.zid && s.subs.is_some() - && (s.face.whatami == WhatAmI::Client - || (s.face.whatami == WhatAmI::Peer - && hat!(tables).failover_brokering(s.face.zid, face.zid))) + && (s.face.state.whatami == WhatAmI::Client + || (s.face.state.whatami == WhatAmI::Peer + && hat!(tables) + .failover_brokering(s.face.state.zid, face.state.zid))) }) { - if let Some(id) = face_hat_mut!(&mut face).local_subs.remove(res) { + if let Some(id) = face_hat_mut!(&mut face.state).local_subs.remove(res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + &face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } } @@ -667,26 +666,24 @@ pub(super) fn undeclare_simple_subscription( } if simple_subs.len() == 1 && !router_subs && !linkstatepeer_subs { - let mut face = &mut simple_subs[0]; - if let Some(id) = face_hat_mut!(face).local_subs.remove(res) { + let face = &mut simple_subs[0]; + if let Some(id) = face_hat_mut!(&mut face.state).local_subs.remove(res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } - for res in face_hat!(face) + for res in face_hat!(face.state) .local_subs .keys() .cloned() @@ -695,27 +692,25 @@ pub(super) fn undeclare_simple_subscription( if !res.context().matches.iter().any(|m| { m.upgrade().is_some_and(|m| { m.context.is_some() - && (remote_simple_subs(&m, face) + && (remote_simple_subs(&m, &face.state) || remote_linkstatepeer_subs(tables, &m) || remote_router_subs(tables, &m)) }) }) { - if let Some(id) = face_hat_mut!(&mut face).local_subs.remove(&res) { + if let Some(id) = face_hat_mut!(&mut face.state).local_subs.remove(&res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } } @@ -844,74 +839,73 @@ pub(super) fn pubsub_linkstate_change( send_declare: &mut SendDeclare, ) { if let Some(mut src_face) = tables.get_face(zid).cloned() { - if hat!(tables).router_peers_failover_brokering && src_face.whatami == WhatAmI::Peer { - let to_forget = face_hat!(src_face) + if hat!(tables).router_peers_failover_brokering && src_face.state.whatami == WhatAmI::Peer { + let to_forget = face_hat!(src_face.state) .local_subs .keys() .filter(|res| { let client_subs = res .session_ctxs .values() - .any(|ctx| ctx.face.whatami == WhatAmI::Client && ctx.subs.is_some()); + .any(|ctx| ctx.face.state.whatami == WhatAmI::Client && ctx.subs.is_some()); !remote_router_subs(tables, res) && !client_subs && !res.session_ctxs.values().any(|ctx| { - ctx.face.whatami == WhatAmI::Peer - && src_face.id != ctx.face.id - && HatTables::failover_brokering_to(links, ctx.face.zid) + ctx.face.state.whatami == WhatAmI::Peer + && src_face.state.id != ctx.face.state.id + && HatTables::failover_brokering_to(links, ctx.face.state.zid) }) }) .cloned() .collect::>>(); for res in to_forget { - if let Some(id) = face_hat_mut!(&mut src_face).local_subs.remove(&res) { - let wire_expr = Resource::get_best_key(&res, "", src_face.id); + if let Some(id) = face_hat_mut!(&mut src_face.state).local_subs.remove(&res) { + let wire_expr = Resource::get_best_key(&res, "", src_face.state.id); send_declare( - &src_face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::default(), - body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { - id, - ext_wire_expr: WireExprType { wire_expr }, - }), - }, - res.expr().to_string(), - ), + &src_face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::UndeclareSubscriber(UndeclareSubscriber { + id, + ext_wire_expr: WireExprType { wire_expr }, + }), + }, + Some(res.clone()), ); } } for mut dst_face in tables.faces.values().cloned() { - if src_face.id != dst_face.id - && HatTables::failover_brokering_to(links, dst_face.zid) + if src_face.state.id != dst_face.state.id + && HatTables::failover_brokering_to(links, dst_face.state.zid) { - for res in face_hat!(src_face).remote_subs.values() { - if !face_hat!(dst_face).local_subs.contains_key(res) { - let id = face_hat!(dst_face).next_id.fetch_add(1, Ordering::SeqCst); - face_hat_mut!(&mut dst_face) + for res in face_hat!(src_face.state).remote_subs.values() { + if !face_hat!(dst_face.state).local_subs.contains_key(res) { + let id = face_hat!(dst_face.state) + .next_id + .fetch_add(1, Ordering::SeqCst); + face_hat_mut!(&mut dst_face.state) .local_subs .insert(res.clone(), id); - let push_declaration = push_declaration_profile(tables, &dst_face); - let key_expr = Resource::decl_key(res, &mut dst_face, push_declaration); + let push_declaration = + push_declaration_profile(tables, &dst_face.state); + let key_expr = Resource::decl_key(res, &dst_face, push_declaration); send_declare( - &dst_face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::default(), - body: DeclareBody::DeclareSubscriber(DeclareSubscriber { - id, - wire_expr: key_expr, - }), - }, - res.expr().to_string(), - ), + &dst_face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::DeclareSubscriber(DeclareSubscriber { + id, + wire_expr: key_expr, + }), + }, + Some(res.clone()), ); } } @@ -938,7 +932,7 @@ fn make_sub_id(res: &Arc, face: &mut Arc, mode: InterestMod pub(crate) fn declare_sub_interest( tables: &mut Tables, - face: &mut Arc, + face: &Face, id: InterestId, res: Option<&mut Arc>, mode: InterestMode, @@ -952,28 +946,29 @@ pub(crate) fn declare_sub_interest( if hat!(tables).router_subs.iter().any(|sub| { sub.context.is_some() && sub.matches(res) - && (remote_simple_subs(sub, face) + && (remote_simple_subs(sub, &face.state) || remote_linkstatepeer_subs(tables, sub) || remote_router_subs(tables, sub)) }) { - let id = make_sub_id(res, face, mode); - let wire_expr = - Resource::decl_key(res, face, push_declaration_profile(tables, face)); + let id = make_sub_id(res, &mut face.state.clone(), mode); + let wire_expr = Resource::decl_key( + res, + face, + push_declaration_profile(tables, &face.state), + ); send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareSubscriber(DeclareSubscriber { - id, - wire_expr, - }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareSubscriber(DeclareSubscriber { + id, + wire_expr, + }), + }, + Some(res.deref().clone()), ); } } else { @@ -986,33 +981,36 @@ pub(crate) fn declare_sub_interest( .iter() .any(|r| *r != tables.zid) || sub.session_ctxs.values().any(|s| { - s.face.id != face.id + s.face.state.id != face.state.id && s.subs.is_some() - && (s.face.whatami == WhatAmI::Client - || face.whatami == WhatAmI::Client - || (s.face.whatami == WhatAmI::Peer - && hat!(tables) - .failover_brokering(s.face.zid, face.zid))) + && (s.face.state.whatami == WhatAmI::Client + || face.state.whatami == WhatAmI::Client + || (s.face.state.whatami == WhatAmI::Peer + && hat!(tables).failover_brokering( + s.face.state.zid, + face.state.zid, + ))) })) { - let id = make_sub_id(sub, face, mode); - let wire_expr = - Resource::decl_key(sub, face, push_declaration_profile(tables, face)); + let id = make_sub_id(sub, &mut face.state.clone(), mode); + let wire_expr = Resource::decl_key( + sub, + face, + push_declaration_profile(tables, &face.state), + ); send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareSubscriber(DeclareSubscriber { - id, - wire_expr, - }), - }, - sub.expr().to_string(), - ), + face, + Declare { + interest_id, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareSubscriber(DeclareSubscriber { + id, + wire_expr, + }), + }, + Some(sub.clone()), ); } } @@ -1027,29 +1025,31 @@ pub(crate) fn declare_sub_interest( .any(|r| *r != tables.zid) || sub.session_ctxs.values().any(|s| { s.subs.is_some() - && (s.face.whatami != WhatAmI::Peer - || face.whatami != WhatAmI::Peer - || hat!(tables).failover_brokering(s.face.zid, face.zid)) + && (s.face.state.whatami != WhatAmI::Peer + || face.state.whatami != WhatAmI::Peer + || hat!(tables) + .failover_brokering(s.face.state.zid, face.state.zid)) })) { - let id = make_sub_id(sub, face, mode); - let wire_expr = - Resource::decl_key(sub, face, push_declaration_profile(tables, face)); + let id = make_sub_id(sub, &mut face.state.clone(), mode); + let wire_expr = Resource::decl_key( + sub, + face, + push_declaration_profile(tables, &face.state), + ); send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareSubscriber(DeclareSubscriber { - id, - wire_expr, - }), - }, - sub.expr().to_string(), - ), + face, + Declare { + interest_id, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareSubscriber(DeclareSubscriber { + id, + wire_expr, + }), + }, + Some(sub.clone()), ); } } @@ -1061,25 +1061,32 @@ impl HatPubSubTrait for HatCode { fn declare_subscription( &self, tables: &mut Tables, - face: &mut Arc, + face: &Face, id: SubscriberId, res: &mut Arc, sub_info: &SubscriberInfo, node_id: NodeId, send_declare: &mut SendDeclare, ) { - match face.whatami { + match face.state.whatami { WhatAmI::Router => { - if let Some(router) = get_router(tables, face, node_id) { - declare_router_subscription(tables, face, res, sub_info, router, send_declare) + if let Some(router) = get_router(tables, &face.state.clone(), node_id) { + declare_router_subscription( + tables, + &mut face.state.clone(), + res, + sub_info, + router, + send_declare, + ) } } WhatAmI::Peer => { if hat!(tables).full_net(WhatAmI::Peer) { - if let Some(peer) = get_peer(tables, face, node_id) { + if let Some(peer) = get_peer(tables, &face.state, node_id) { declare_linkstatepeer_subscription( tables, - face, + &mut face.state.clone(), res, sub_info, peer, @@ -1160,8 +1167,8 @@ impl HatPubSubTrait for HatCode { s.session_ctxs .values() .filter_map(|f| { - (f.face.whatami == WhatAmI::Peer && f.subs.is_some()) - .then_some(f.face.zid) + (f.face.state.whatami == WhatAmI::Peer && f.subs.is_some()) + .then_some(f.face.state.zid) }) .collect() }, @@ -1169,8 +1176,8 @@ impl HatPubSubTrait for HatCode { .session_ctxs .values() .filter_map(|f| { - (f.face.whatami == WhatAmI::Client && f.subs.is_some()) - .then_some(f.face.zid) + (f.face.state.whatami == WhatAmI::Client && f.subs.is_some()) + .then_some(f.face.state.zid) }) .collect(), }, @@ -1182,14 +1189,14 @@ impl HatPubSubTrait for HatCode { fn get_publications(&self, tables: &Tables) -> Vec<(Arc, Sources)> { let mut result = HashMap::new(); for face in tables.faces.values() { - for interest in face_hat!(face).remote_interests.values() { + for interest in face_hat!(face.state).remote_interests.values() { if interest.options.subscribers() { if let Some(res) = interest.res.as_ref() { let sources = result.entry(res.clone()).or_insert_with(Sources::default); - match face.whatami { - WhatAmI::Router => sources.routers.push(face.zid), - WhatAmI::Peer => sources.peers.push(face.zid), - WhatAmI::Client => sources.clients.push(face.zid), + match face.state.whatami { + WhatAmI::Router => sources.routers.push(face.state.zid), + WhatAmI::Peer => sources.peers.push(face.state.zid), + WhatAmI::Client => sources.clients.push(face.state.zid), } } } @@ -1223,11 +1230,11 @@ impl HatPubSubTrait for HatCode { { if net.graph.contains_node(direction) { if let Some(face) = tables.get_face(&net.graph[direction].zid) { - route.entry(face.id).or_insert_with(|| { + route.entry(face.state.id).or_insert_with(|| { let key_expr = Resource::get_best_key( expr.prefix, expr.suffix, - face.id, + face.state.id, ); (face.clone(), key_expr.to_owned(), source) }); @@ -1308,7 +1315,7 @@ impl HatPubSubTrait for HatCode { if master || source_type == WhatAmI::Router { for (sid, context) in &mres.session_ctxs { - if context.subs.is_some() && context.face.whatami != WhatAmI::Router { + if context.subs.is_some() && context.face.state.whatami != WhatAmI::Router { route.entry(*sid).or_insert_with(|| { let key_expr = Resource::get_best_key(expr.prefix, expr.suffix, *sid); (context.face.clone(), key_expr.to_owned(), NodeId::default()) @@ -1319,7 +1326,7 @@ impl HatPubSubTrait for HatCode { } for mcast_group in &tables.mcast_groups { route.insert( - mcast_group.id, + mcast_group.state.id, ( mcast_group.clone(), expr.full_expr().to_string().into(), @@ -1351,7 +1358,9 @@ impl HatPubSubTrait for HatCode { if let Some(direction) = net.trees[source].directions[sub_idx.index()] { if net.graph.contains_node(direction) { if let Some(face) = tables.get_face(&net.graph[direction].zid) { - route.entry(face.id).or_insert_with(|| face.clone()); + route + .entry(face.state.id) + .or_insert_with(|| face.state.clone()); } } } @@ -1407,10 +1416,10 @@ impl HatPubSubTrait for HatCode { if master { for (sid, context) in &mres.session_ctxs { - if context.subs.is_some() && context.face.whatami != WhatAmI::Router { + if context.subs.is_some() && context.face.state.whatami != WhatAmI::Router { matching_subscriptions .entry(*sid) - .or_insert_with(|| context.face.clone()); + .or_insert_with(|| context.face.state.clone()); } } } diff --git a/zenoh/src/net/routing/hat/router/queries.rs b/zenoh/src/net/routing/hat/router/queries.rs index 6b0a6f284b..0ffbabe2a7 100644 --- a/zenoh/src/net/routing/hat/router/queries.rs +++ b/zenoh/src/net/routing/hat/router/queries.rs @@ -14,6 +14,7 @@ use std::{ borrow::Cow, collections::HashMap, + ops::Deref, sync::{atomic::Ordering, Arc}, }; @@ -44,13 +45,12 @@ use super::{ use crate::key_expr::KeyExpr; use crate::net::routing::{ dispatcher::{ - face::FaceState, + face::{Face, FaceState}, resource::{NodeId, Resource, SessionContext}, tables::{QueryTargetQabl, QueryTargetQablSet, RoutingExpr, Tables}, }, hat::{CurrentFutureTrait, HatQueriesTrait, SendDeclare, Sources}, router::disable_matches_query_routes, - RoutingContext, }; #[inline] @@ -168,9 +168,9 @@ fn local_qabl_info( res.session_ctxs .values() .fold(info, |accu, ctx| { - if ctx.face.id != face.id && ctx.face.whatami != WhatAmI::Peer + if ctx.face.state.id != face.id && ctx.face.state.whatami != WhatAmI::Peer || face.whatami != WhatAmI::Peer - || hat!(tables).failover_brokering(ctx.face.zid, face.zid) + || hat!(tables).failover_brokering(ctx.face.state.zid, face.zid) { if let Some(info) = ctx.qabl.as_ref() { Some(match accu { @@ -200,16 +200,16 @@ fn send_sourced_queryable_to_net_children( for child in children { if net.graph.contains_node(*child) { match tables.get_face(&net.graph[*child].zid).cloned() { - Some(mut someface) => { + Some(someface) => { if src_face .as_ref() - .map(|src_face| someface.id != src_face.id) + .map(|src_face| someface.state.id != src_face.id) .unwrap_or(true) { - let push_declaration = push_declaration_profile(tables, &someface); - let key_expr = Resource::decl_key(res, &mut someface, push_declaration); + let push_declaration = push_declaration_profile(tables, &someface.state); + let key_expr = Resource::decl_key(res, &someface, push_declaration); - someface.primitives.send_declare(RoutingContext::with_expr( + someface.intercept_declare( &mut Declare { interest_id: None, ext_qos: ext::QoSType::DECLARE, @@ -223,8 +223,8 @@ fn send_sourced_queryable_to_net_children( ext_info: *qabl_info, }), }, - res.expr().to_string(), - )); + Some(res), + ); } } None => tracing::trace!("Unable to find face for zid {}", net.graph[*child].zid), @@ -242,55 +242,55 @@ fn propagate_simple_queryable( let full_peers_net = hat!(tables).full_net(WhatAmI::Peer); let faces = tables.faces.values().cloned(); for mut dst_face in faces { - let info = local_qabl_info(tables, res, &dst_face); - let current = face_hat!(dst_face).local_qabls.get(res); + let info = local_qabl_info(tables, res, &dst_face.state); + let current = face_hat!(dst_face.state).local_qabls.get(res); if src_face .as_ref() - .map(|src_face| dst_face.id != src_face.id) + .map(|src_face| dst_face.state.id != src_face.id) .unwrap_or(true) && (current.is_none() || current.unwrap().1 != info) - && face_hat!(dst_face) + && face_hat!(dst_face.state) .remote_interests .values() .any(|i| i.options.queryables() && i.matches(res)) && if full_peers_net { - dst_face.whatami == WhatAmI::Client + dst_face.state.whatami == WhatAmI::Client } else { - dst_face.whatami != WhatAmI::Router + dst_face.state.whatami != WhatAmI::Router && src_face .as_ref() .map(|src_face| { src_face.whatami != WhatAmI::Peer - || dst_face.whatami != WhatAmI::Peer - || hat!(tables).failover_brokering(src_face.zid, dst_face.zid) + || dst_face.state.whatami != WhatAmI::Peer + || hat!(tables).failover_brokering(src_face.zid, dst_face.state.zid) }) .unwrap_or(true) } { - let id = current - .map(|c| c.0) - .unwrap_or(face_hat!(dst_face).next_id.fetch_add(1, Ordering::SeqCst)); - face_hat_mut!(&mut dst_face) + let id = current.map(|c| c.0).unwrap_or( + face_hat!(dst_face.state) + .next_id + .fetch_add(1, Ordering::SeqCst), + ); + face_hat_mut!(&mut dst_face.state) .local_qabls .insert(res.clone(), (id, info)); - let push_declaration = push_declaration_profile(tables, &dst_face); - let key_expr = Resource::decl_key(res, &mut dst_face, push_declaration); + let push_declaration = push_declaration_profile(tables, &dst_face.state); + let key_expr = Resource::decl_key(res, &dst_face, push_declaration); send_declare( - &dst_face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareQueryable(DeclareQueryable { - id, - wire_expr: key_expr, - ext_info: info, - }), - }, - res.expr().to_string(), - ), + &dst_face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareQueryable(DeclareQueryable { + id, + wire_expr: key_expr, + ext_info: info, + }), + }, + Some(res.clone()), ); } } @@ -429,7 +429,7 @@ fn declare_linkstatepeer_queryable( fn register_simple_queryable( _tables: &mut Tables, - face: &mut Arc, + face: &Face, id: QueryableId, res: &mut Arc, qabl_info: &QueryableInfoType, @@ -439,17 +439,19 @@ fn register_simple_queryable( let res = get_mut_unchecked(res); get_mut_unchecked( res.session_ctxs - .entry(face.id) + .entry(face.state.id) .or_insert_with(|| Arc::new(SessionContext::new(face.clone()))), ) .qabl = Some(*qabl_info); } - face_hat_mut!(face).remote_qabls.insert(id, res.clone()); + face_hat_mut!(&mut face.state.clone()) + .remote_qabls + .insert(id, res.clone()); } fn declare_simple_queryable( tables: &mut Tables, - face: &mut Arc, + face: &Face, id: QueryableId, res: &mut Arc, qabl_info: &QueryableInfoType, @@ -458,7 +460,14 @@ fn declare_simple_queryable( register_simple_queryable(tables, face, id, res, qabl_info); let local_details = local_router_qabl_info(tables, res); let zid = tables.zid; - register_router_queryable(tables, Some(face), res, &local_details, zid, send_declare); + register_router_queryable( + tables, + Some(&mut face.state.clone()), + res, + &local_details, + zid, + send_declare, + ); } #[inline] @@ -480,7 +489,7 @@ fn remote_linkstatepeer_qabls(tables: &Tables, res: &Arc) -> bool { } #[inline] -fn simple_qabls(res: &Arc) -> Vec> { +fn simple_qabls(res: &Arc) -> Vec { res.session_ctxs .values() .filter_map(|ctx| { @@ -497,7 +506,7 @@ fn simple_qabls(res: &Arc) -> Vec> { fn remote_simple_qabls(res: &Arc, face: &Arc) -> bool { res.session_ctxs .values() - .any(|ctx| ctx.face.id != face.id && ctx.qabl.is_some()) + .any(|ctx| ctx.face.state.id != face.id && ctx.qabl.is_some()) } #[inline] @@ -512,15 +521,15 @@ fn send_forget_sourced_queryable_to_net_children( for child in children { if net.graph.contains_node(*child) { match tables.get_face(&net.graph[*child].zid).cloned() { - Some(mut someface) => { + Some(someface) => { if src_face - .map(|src_face| someface.id != src_face.id) + .map(|src_face| someface.state.id != src_face.id) .unwrap_or(true) { - let push_declaration = push_declaration_profile(tables, &someface); - let wire_expr = Resource::decl_key(res, &mut someface, push_declaration); + let push_declaration = push_declaration_profile(tables, &someface.state); + let wire_expr = Resource::decl_key(res, &someface, push_declaration); - someface.primitives.send_declare(RoutingContext::with_expr( + someface.intercept_declare( &mut Declare { interest_id: None, ext_qos: ext::QoSType::DECLARE, @@ -533,8 +542,8 @@ fn send_forget_sourced_queryable_to_net_children( ext_wire_expr: WireExprType { wire_expr }, }), }, - res.expr().to_string(), - )); + Some(res), + ); } } None => tracing::trace!("Unable to find face for zid {}", net.graph[*child].zid), @@ -549,25 +558,23 @@ fn propagate_forget_simple_queryable( send_declare: &mut SendDeclare, ) { for mut face in tables.faces.values().cloned() { - if let Some((id, _)) = face_hat_mut!(&mut face).local_qabls.remove(res) { + if let Some((id, _)) = face_hat_mut!(&mut face.state).local_qabls.remove(res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareQueryable(UndeclareQueryable { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + &face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareQueryable(UndeclareQueryable { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } - for res in face_hat!(&mut face) + for res in face_hat!(&mut face.state) .local_qabls .keys() .cloned() @@ -576,27 +583,25 @@ fn propagate_forget_simple_queryable( if !res.context().matches.iter().any(|m| { m.upgrade().is_some_and(|m| { m.context.is_some() - && (remote_simple_qabls(&m, &face) + && (remote_simple_qabls(&m, &face.state) || remote_linkstatepeer_qabls(tables, &m) || remote_router_qabls(tables, &m)) }) }) { - if let Some((id, _)) = face_hat_mut!(&mut face).local_qabls.remove(&res) { + if let Some((id, _)) = face_hat_mut!(&mut face.state).local_qabls.remove(&res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareQueryable(UndeclareQueryable { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + &face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareQueryable(UndeclareQueryable { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } } @@ -613,38 +618,32 @@ fn propagate_forget_simple_queryable_to_peers( && res_hat!(res).router_qabls.len() == 1 && res_hat!(res).router_qabls.contains_key(&tables.zid) { - for mut face in tables - .faces - .values() - .cloned() - .collect::>>() - { - if face.whatami == WhatAmI::Peer - && face_hat!(face).local_qabls.contains_key(res) + for mut face in tables.faces.values().cloned().collect::>() { + if face.state.whatami == WhatAmI::Peer + && face_hat!(face.state).local_qabls.contains_key(res) && !res.session_ctxs.values().any(|s| { - face.zid != s.face.zid + face.state.zid != s.face.state.zid && s.qabl.is_some() - && (s.face.whatami == WhatAmI::Client - || (s.face.whatami == WhatAmI::Peer - && hat!(tables).failover_brokering(s.face.zid, face.zid))) + && (s.face.state.whatami == WhatAmI::Client + || (s.face.state.whatami == WhatAmI::Peer + && hat!(tables) + .failover_brokering(s.face.state.zid, face.state.zid))) }) { - if let Some((id, _)) = face_hat_mut!(&mut face).local_qabls.remove(res) { + if let Some((id, _)) = face_hat_mut!(&mut face.state).local_qabls.remove(res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareQueryable(UndeclareQueryable { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + &face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareQueryable(UndeclareQueryable { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } } @@ -807,26 +806,24 @@ pub(super) fn undeclare_simple_queryable( } if simple_qabls.len() == 1 && !router_qabls && !linkstatepeer_qabls { - let mut face = &mut simple_qabls[0]; - if let Some((id, _)) = face_hat_mut!(face).local_qabls.remove(res) { + let face = &mut simple_qabls[0]; + if let Some((id, _)) = face_hat_mut!(&mut face.state).local_qabls.remove(res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareQueryable(UndeclareQueryable { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareQueryable(UndeclareQueryable { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } - for res in face_hat!(face) + for res in face_hat!(face.state) .local_qabls .keys() .cloned() @@ -835,27 +832,25 @@ pub(super) fn undeclare_simple_queryable( if !res.context().matches.iter().any(|m| { m.upgrade().is_some_and(|m| { m.context.is_some() - && (remote_simple_qabls(&m, face) + && (remote_simple_qabls(&m, &face.state) || remote_linkstatepeer_qabls(tables, &m) || remote_router_qabls(tables, &m)) }) }) { - if let Some((id, _)) = face_hat_mut!(&mut face).local_qabls.remove(&res) { + if let Some((id, _)) = face_hat_mut!(&mut face.state).local_qabls.remove(&res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareQueryable(UndeclareQueryable { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareQueryable(UndeclareQueryable { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } } @@ -950,76 +945,75 @@ pub(super) fn queries_linkstate_change( send_declare: &mut SendDeclare, ) { if let Some(mut src_face) = tables.get_face(zid).cloned() { - if hat!(tables).router_peers_failover_brokering && src_face.whatami == WhatAmI::Peer { - let to_forget = face_hat!(src_face) + if hat!(tables).router_peers_failover_brokering && src_face.state.whatami == WhatAmI::Peer { + let to_forget = face_hat!(src_face.state) .local_qabls .keys() .filter(|res| { let client_qabls = res .session_ctxs .values() - .any(|ctx| ctx.face.whatami == WhatAmI::Client && ctx.qabl.is_some()); + .any(|ctx| ctx.face.state.whatami == WhatAmI::Client && ctx.qabl.is_some()); !remote_router_qabls(tables, res) && !client_qabls && !res.session_ctxs.values().any(|ctx| { - ctx.face.whatami == WhatAmI::Peer - && src_face.id != ctx.face.id - && HatTables::failover_brokering_to(links, ctx.face.zid) + ctx.face.state.whatami == WhatAmI::Peer + && src_face.state.id != ctx.face.state.id + && HatTables::failover_brokering_to(links, ctx.face.state.zid) }) }) .cloned() .collect::>>(); for res in to_forget { - if let Some((id, _)) = face_hat_mut!(&mut src_face).local_qabls.remove(&res) { - let wire_expr = Resource::get_best_key(&res, "", src_face.id); + if let Some((id, _)) = face_hat_mut!(&mut src_face.state).local_qabls.remove(&res) { + let wire_expr = Resource::get_best_key(&res, "", src_face.state.id); send_declare( - &src_face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::default(), - body: DeclareBody::UndeclareQueryable(UndeclareQueryable { - id, - ext_wire_expr: WireExprType { wire_expr }, - }), - }, - res.expr().to_string(), - ), + &src_face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::UndeclareQueryable(UndeclareQueryable { + id, + ext_wire_expr: WireExprType { wire_expr }, + }), + }, + Some(res.clone()), ); } } for mut dst_face in tables.faces.values().cloned() { - if src_face.id != dst_face.id - && HatTables::failover_brokering_to(links, dst_face.zid) + if src_face.state.id != dst_face.state.id + && HatTables::failover_brokering_to(links, dst_face.state.zid) { - for res in face_hat!(src_face).remote_qabls.values() { - if !face_hat!(dst_face).local_qabls.contains_key(res) { - let id = face_hat!(dst_face).next_id.fetch_add(1, Ordering::SeqCst); - let info = local_qabl_info(tables, res, &dst_face); - face_hat_mut!(&mut dst_face) + for res in face_hat!(src_face.state).remote_qabls.values() { + if !face_hat!(dst_face.state).local_qabls.contains_key(res) { + let id = face_hat!(dst_face.state) + .next_id + .fetch_add(1, Ordering::SeqCst); + let info = local_qabl_info(tables, res, &dst_face.state); + face_hat_mut!(&mut dst_face.state) .local_qabls .insert(res.clone(), (id, info)); - let push_declaration = push_declaration_profile(tables, &dst_face); - let key_expr = Resource::decl_key(res, &mut dst_face, push_declaration); + let push_declaration = + push_declaration_profile(tables, &dst_face.state); + let key_expr = Resource::decl_key(res, &dst_face, push_declaration); send_declare( - &dst_face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::default(), - body: DeclareBody::DeclareQueryable(DeclareQueryable { - id, - wire_expr: key_expr, - ext_info: info, - }), - }, - res.expr().to_string(), - ), + &dst_face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::DeclareQueryable(DeclareQueryable { + id, + wire_expr: key_expr, + ext_info: info, + }), + }, + Some(res.clone()), ); } } @@ -1094,8 +1088,11 @@ fn insert_target_for_qabls( if net.graph.contains_node(direction) { if let Some(face) = tables.get_face(&net.graph[direction].zid) { if net.distances.len() > qabl_idx.index() { - let key_expr = - Resource::get_best_key(expr.prefix, expr.suffix, face.id); + let key_expr = Resource::get_best_key( + expr.prefix, + expr.suffix, + face.state.id, + ); route.push(QueryTargetQabl { direction: (face.clone(), key_expr.to_owned(), source), info: Some(QueryableInfoType { @@ -1143,7 +1140,7 @@ fn make_qabl_id( pub(crate) fn declare_qabl_interest( tables: &mut Tables, - face: &mut Arc, + face: &Face, id: InterestId, res: Option<&mut Arc>, mode: InterestMode, @@ -1163,35 +1160,38 @@ pub(crate) fn declare_qabl_interest( .keys() .any(|r| *r != tables.zid) || qabl.session_ctxs.values().any(|s| { - s.face.id != face.id + s.face.state.id != face.state.id && s.qabl.is_some() - && (s.face.whatami == WhatAmI::Client - || face.whatami == WhatAmI::Client - || (s.face.whatami == WhatAmI::Peer - && hat!(tables) - .failover_brokering(s.face.zid, face.zid))) + && (s.face.state.whatami == WhatAmI::Client + || face.state.whatami == WhatAmI::Client + || (s.face.state.whatami == WhatAmI::Peer + && hat!(tables).failover_brokering( + s.face.state.zid, + face.state.zid, + ))) })) }) { - let info = local_qabl_info(tables, res, face); - let id = make_qabl_id(res, face, mode, info); - let wire_expr = - Resource::decl_key(res, face, push_declaration_profile(tables, face)); + let info = local_qabl_info(tables, res, &face.state); + let id = make_qabl_id(res, &mut face.state.clone(), mode, info); + let wire_expr = Resource::decl_key( + res, + face, + push_declaration_profile(tables, &face.state), + ); send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareQueryable(DeclareQueryable { - id, - wire_expr, - ext_info: info, - }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareQueryable(DeclareQueryable { + id, + wire_expr, + ext_info: info, + }), + }, + Some(res.deref().clone()), ); } } else { @@ -1205,49 +1205,21 @@ pub(crate) fn declare_qabl_interest( .any(|r| *r != tables.zid) || qabl.session_ctxs.values().any(|s| { s.qabl.is_some() - && (s.face.whatami != WhatAmI::Peer - || face.whatami != WhatAmI::Peer - || hat!(tables).failover_brokering(s.face.zid, face.zid)) + && (s.face.state.whatami != WhatAmI::Peer + || face.state.whatami != WhatAmI::Peer + || hat!(tables) + .failover_brokering(s.face.state.zid, face.state.zid)) })) { - let info = local_qabl_info(tables, qabl, face); - let id = make_qabl_id(qabl, face, mode, info); - let key_expr = - Resource::decl_key(qabl, face, push_declaration_profile(tables, face)); - send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareQueryable(DeclareQueryable { - id, - wire_expr: key_expr, - ext_info: info, - }), - }, - qabl.expr().to_string(), - ), + let info = local_qabl_info(tables, qabl, &face.state); + let id = make_qabl_id(qabl, &mut face.state.clone(), mode, info); + let key_expr = Resource::decl_key( + qabl, + face, + push_declaration_profile(tables, &face.state), ); - } - } - } - } else { - for qabl in hat!(tables).router_qabls.iter() { - if qabl.context.is_some() - && (remote_simple_qabls(qabl, face) - || remote_linkstatepeer_qabls(tables, qabl) - || remote_router_qabls(tables, qabl)) - { - let info = local_qabl_info(tables, qabl, face); - let id = make_qabl_id(qabl, face, mode, info); - let key_expr = - Resource::decl_key(qabl, face, push_declaration_profile(tables, face)); - send_declare( - &face.primitives, - RoutingContext::with_expr( + send_declare( + face, Declare { interest_id, ext_qos: ext::QoSType::DECLARE, @@ -1259,8 +1231,39 @@ pub(crate) fn declare_qabl_interest( ext_info: info, }), }, - qabl.expr().to_string(), - ), + Some(qabl.clone()), + ); + } + } + } + } else { + for qabl in hat!(tables).router_qabls.iter() { + if qabl.context.is_some() + && (remote_simple_qabls(qabl, &face.state) + || remote_linkstatepeer_qabls(tables, qabl) + || remote_router_qabls(tables, qabl)) + { + let info = local_qabl_info(tables, qabl, &face.state); + let id = make_qabl_id(qabl, &mut face.state.clone(), mode, info); + let key_expr = Resource::decl_key( + qabl, + face, + push_declaration_profile(tables, &face.state), + ); + send_declare( + face, + Declare { + interest_id, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareQueryable(DeclareQueryable { + id, + wire_expr: key_expr, + ext_info: info, + }), + }, + Some(qabl.clone()), ); } } @@ -1272,25 +1275,32 @@ impl HatQueriesTrait for HatCode { fn declare_queryable( &self, tables: &mut Tables, - face: &mut Arc, + face: &Face, id: QueryableId, res: &mut Arc, qabl_info: &QueryableInfoType, node_id: NodeId, send_declare: &mut SendDeclare, ) { - match face.whatami { + match face.state.whatami { WhatAmI::Router => { - if let Some(router) = get_router(tables, face, node_id) { - declare_router_queryable(tables, face, res, qabl_info, router, send_declare) + if let Some(router) = get_router(tables, &face.state, node_id) { + declare_router_queryable( + tables, + &mut face.state.clone(), + res, + qabl_info, + router, + send_declare, + ) } } WhatAmI::Peer => { if hat!(tables).full_net(WhatAmI::Peer) { - if let Some(peer) = get_peer(tables, face, node_id) { + if let Some(peer) = get_peer(tables, &face.state, node_id) { declare_linkstatepeer_queryable( tables, - face, + &mut face.state.clone(), res, qabl_info, peer, @@ -1371,8 +1381,8 @@ impl HatQueriesTrait for HatCode { s.session_ctxs .values() .filter_map(|f| { - (f.face.whatami == WhatAmI::Peer && f.qabl.is_some()) - .then_some(f.face.zid) + (f.face.state.whatami == WhatAmI::Peer && f.qabl.is_some()) + .then_some(f.face.state.zid) }) .collect() }, @@ -1380,8 +1390,8 @@ impl HatQueriesTrait for HatCode { .session_ctxs .values() .filter_map(|f| { - (f.face.whatami == WhatAmI::Client && f.qabl.is_some()) - .then_some(f.face.zid) + (f.face.state.whatami == WhatAmI::Client && f.qabl.is_some()) + .then_some(f.face.state.zid) }) .collect(), }, @@ -1393,14 +1403,14 @@ impl HatQueriesTrait for HatCode { fn get_queriers(&self, tables: &Tables) -> Vec<(Arc, Sources)> { let mut result = HashMap::new(); for face in tables.faces.values() { - for interest in face_hat!(face).remote_interests.values() { + for interest in face_hat!(face.state).remote_interests.values() { if interest.options.queryables() { if let Some(res) = interest.res.as_ref() { let sources = result.entry(res.clone()).or_insert_with(Sources::default); - match face.whatami { - WhatAmI::Router => sources.routers.push(face.zid), - WhatAmI::Peer => sources.peers.push(face.zid), - WhatAmI::Client => sources.clients.push(face.zid), + match face.state.whatami { + WhatAmI::Router => sources.routers.push(face.state.zid), + WhatAmI::Peer => sources.peers.push(face.state.zid), + WhatAmI::Client => sources.clients.push(face.state.zid), } } } @@ -1484,7 +1494,7 @@ impl HatQueriesTrait for HatCode { if master || source_type == WhatAmI::Router { for (sid, context) in &mres.session_ctxs { - if context.face.whatami != WhatAmI::Router { + if context.face.state.whatami != WhatAmI::Router { let key_expr = Resource::get_best_key(expr.prefix, expr.suffix, *sid); if let Some(qabl_info) = context.qabl.as_ref() { route.push(QueryTargetQabl { @@ -1568,11 +1578,11 @@ impl HatQueriesTrait for HatCode { if match complete { true => context.qabl.is_some_and(|q| q.complete), false => context.qabl.is_some(), - } && context.face.whatami != WhatAmI::Router + } && context.face.state.whatami != WhatAmI::Router { matching_queryables .entry(*sid) - .or_insert_with(|| context.face.clone()); + .or_insert_with(|| context.face.state.clone()); } } } @@ -1601,7 +1611,9 @@ fn insert_faces_for_qbls( if let Some(direction) = net.trees[source].directions[qbl_idx.index()] { if net.graph.contains_node(direction) { if let Some(face) = tables.get_face(&net.graph[direction].zid) { - route.entry(face.id).or_insert_with(|| face.clone()); + route + .entry(face.state.id) + .or_insert_with(|| face.state.clone()); } } } diff --git a/zenoh/src/net/routing/hat/router/token.rs b/zenoh/src/net/routing/hat/router/token.rs index 172e1c0e6c..29e0e3ccc6 100644 --- a/zenoh/src/net/routing/hat/router/token.rs +++ b/zenoh/src/net/routing/hat/router/token.rs @@ -12,7 +12,10 @@ // ZettaScale Zenoh Team, // -use std::sync::{atomic::Ordering, Arc}; +use std::{ + ops::Deref, + sync::{atomic::Ordering, Arc}, +}; use petgraph::graph::NodeIndex; use zenoh_protocol::{ @@ -31,10 +34,13 @@ use super::{ push_declaration_profile, res_hat, res_hat_mut, HatCode, HatContext, HatFace, HatTables, }; use crate::net::routing::{ - dispatcher::{face::FaceState, interests::RemoteInterest, tables::Tables}, + dispatcher::{ + face::{Face, FaceState}, + interests::RemoteInterest, + tables::Tables, + }, hat::{CurrentFutureTrait, HatTokenTrait, SendDeclare}, router::{NodeId, Resource, SessionContext}, - RoutingContext, }; #[inline] @@ -49,15 +55,15 @@ fn send_sourced_token_to_net_clildren( for child in clildren { if net.graph.contains_node(*child) { match tables.get_face(&net.graph[*child].zid).cloned() { - Some(mut someface) => { + Some(someface) => { if src_face - .map(|src_face| someface.id != src_face.id) + .map(|src_face| someface.state.id != src_face.id) .unwrap_or(true) { - let push_declaration = push_declaration_profile(tables, &someface); - let key_expr = Resource::decl_key(res, &mut someface, push_declaration); + let push_declaration = push_declaration_profile(tables, &someface.state); + let key_expr = Resource::decl_key(res, &someface, push_declaration); - someface.primitives.send_declare(RoutingContext::with_expr( + someface.intercept_declare( &mut Declare { interest_id: None, ext_qos: ext::QoSType::DECLARE, @@ -70,8 +76,8 @@ fn send_sourced_token_to_net_clildren( wire_expr: key_expr, }), }, - res.expr().to_string(), - )); + Some(res), + ); } } None => tracing::trace!("Unable to find face for zid {}", net.graph[*child].zid), @@ -83,24 +89,24 @@ fn send_sourced_token_to_net_clildren( #[inline] fn propagate_simple_token_to( tables: &mut Tables, - dst_face: &mut Arc, + dst_face: &mut Face, res: &Arc, src_face: &mut Arc, full_peer_net: bool, send_declare: &mut SendDeclare, ) { - if (src_face.id != dst_face.id || dst_face.zid == tables.zid) - && !face_hat!(dst_face).local_tokens.contains_key(res) + if (src_face.id != dst_face.state.id || dst_face.state.zid == tables.zid) + && !face_hat!(dst_face.state).local_tokens.contains_key(res) && if full_peer_net { - dst_face.whatami == WhatAmI::Client + dst_face.state.whatami == WhatAmI::Client } else { - dst_face.whatami != WhatAmI::Router + dst_face.state.whatami != WhatAmI::Router && (src_face.whatami != WhatAmI::Peer - || dst_face.whatami != WhatAmI::Peer - || hat!(tables).failover_brokering(src_face.zid, dst_face.zid)) + || dst_face.state.whatami != WhatAmI::Peer + || hat!(tables).failover_brokering(src_face.zid, dst_face.state.zid)) } { - let matching_interests = face_hat!(dst_face) + let matching_interests = face_hat!(dst_face.state) .remote_interests .values() .filter(|i| i.options.tokens() && i.matches(res)) @@ -118,26 +124,31 @@ fn propagate_simple_token_to( } else { res }; - if !face_hat!(dst_face).local_tokens.contains_key(res) { - let id = face_hat!(dst_face).next_id.fetch_add(1, Ordering::SeqCst); - face_hat_mut!(dst_face).local_tokens.insert(res.clone(), id); - let key_expr = - Resource::decl_key(res, dst_face, push_declaration_profile(tables, dst_face)); + if !face_hat!(dst_face.state).local_tokens.contains_key(res) { + let id = face_hat!(dst_face.state) + .next_id + .fetch_add(1, Ordering::SeqCst); + face_hat_mut!(&mut dst_face.state) + .local_tokens + .insert(res.clone(), id); + let key_expr = Resource::decl_key( + res, + dst_face, + push_declaration_profile(tables, &dst_face.state), + ); send_declare( - &dst_face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareToken(DeclareToken { - id, - wire_expr: key_expr, - }), - }, - res.expr().to_string(), - ), + dst_face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareToken(DeclareToken { + id, + wire_expr: key_expr, + }), + }, + Some(res.clone()), ); } } @@ -151,12 +162,7 @@ fn propagate_simple_token( send_declare: &mut SendDeclare, ) { let full_peer_net = hat!(tables).full_net(WhatAmI::Peer); - for mut dst_face in tables - .faces - .values() - .cloned() - .collect::>>() - { + for mut dst_face in tables.faces.values().cloned().collect::>() { propagate_simple_token_to( tables, &mut dst_face, @@ -270,16 +276,11 @@ fn declare_linkstatepeer_token( register_router_token(tables, face, res, zid, send_declare); } -fn register_simple_token( - _tables: &mut Tables, - face: &mut Arc, - id: TokenId, - res: &mut Arc, -) { +fn register_simple_token(_tables: &mut Tables, face: &Face, id: TokenId, res: &mut Arc) { // Register liveliness { let res = get_mut_unchecked(res); - match res.session_ctxs.get_mut(&face.id) { + match res.session_ctxs.get_mut(&face.state.id) { Some(ctx) => { if !ctx.token { get_mut_unchecked(ctx).token = true; @@ -288,25 +289,27 @@ fn register_simple_token( None => { let ctx = res .session_ctxs - .entry(face.id) + .entry(face.state.id) .or_insert_with(|| Arc::new(SessionContext::new(face.clone()))); get_mut_unchecked(ctx).token = true; } } } - face_hat_mut!(face).remote_tokens.insert(id, res.clone()); + face_hat_mut!(&mut face.state.clone()) + .remote_tokens + .insert(id, res.clone()); } fn declare_simple_token( tables: &mut Tables, - face: &mut Arc, + face: &Face, id: TokenId, res: &mut Arc, send_declare: &mut SendDeclare, ) { register_simple_token(tables, face, id, res); let zid = tables.zid; - register_router_token(tables, face, res, zid, send_declare); + register_router_token(tables, &mut face.state.clone(), res, zid, send_declare); } #[inline] @@ -328,7 +331,7 @@ fn remote_linkstatepeer_tokens(tables: &Tables, res: &Arc) -> bool { } #[inline] -fn simple_tokens(res: &Arc) -> Vec> { +fn simple_tokens(res: &Arc) -> Vec { res.session_ctxs .values() .filter_map(|ctx| { @@ -345,7 +348,7 @@ fn simple_tokens(res: &Arc) -> Vec> { fn remote_simple_tokens(tables: &Tables, res: &Arc, face: &Arc) -> bool { res.session_ctxs .values() - .any(|ctx| (ctx.face.id != face.id || face.zid == tables.zid) && ctx.token) + .any(|ctx| (ctx.face.state.id != face.id || face.zid == tables.zid) && ctx.token) } #[inline] @@ -360,15 +363,15 @@ fn send_forget_sourced_token_to_net_clildren( for child in clildren { if net.graph.contains_node(*child) { match tables.get_face(&net.graph[*child].zid).cloned() { - Some(mut someface) => { + Some(someface) => { if src_face - .map(|src_face| someface.id != src_face.id) + .map(|src_face| someface.state.id != src_face.id) .unwrap_or(true) { - let push_declaration = push_declaration_profile(tables, &someface); - let wire_expr = Resource::decl_key(res, &mut someface, push_declaration); + let push_declaration = push_declaration_profile(tables, &someface.state); + let wire_expr = Resource::decl_key(res, &someface, push_declaration); - someface.primitives.send_declare(RoutingContext::with_expr( + someface.intercept_declare( &mut Declare { interest_id: None, ext_qos: ext::QoSType::DECLARE, @@ -381,8 +384,8 @@ fn send_forget_sourced_token_to_net_clildren( ext_wire_expr: WireExprType { wire_expr }, }), }, - res.expr().to_string(), - )); + Some(res), + ); } } None => tracing::trace!("Unable to find face for zid {}", net.graph[*child].zid), @@ -398,33 +401,31 @@ fn propagate_forget_simple_token( send_declare: &mut SendDeclare, ) { for mut face in tables.faces.values().cloned() { - if let Some(id) = face_hat_mut!(&mut face).local_tokens.remove(res) { + if let Some(id) = face_hat_mut!(&mut face.state).local_tokens.remove(res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareToken(UndeclareToken { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + &face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareToken(UndeclareToken { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); // NOTE(fuzzypixelz): We need to check that `face` is not the source Face of the token // undeclaration, otherwise the undeclaration would be duplicated at the source Face. In // cases where we don't have access to a Face as we didnt't receive an undeclaration and we // default to true. } else if src_face.map_or(true, |src_face| { - src_face.id != face.id + src_face.id != face.state.id && (src_face.whatami != WhatAmI::Peer - || face.whatami != WhatAmI::Peer - || hat!(tables).failover_brokering(src_face.zid, face.zid)) - }) && face_hat!(face) + || face.state.whatami != WhatAmI::Peer + || hat!(tables).failover_brokering(src_face.zid, face.state.zid)) + }) && face_hat!(face.state) .remote_interests .values() .any(|i| i.options.tokens() && i.matches(res) && !i.options.aggregate()) @@ -432,25 +433,23 @@ fn propagate_forget_simple_token( // Token has never been declared on this face. // Send an Undeclare with a one shot generated id and a WireExpr ext. send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareToken(UndeclareToken { - id: face_hat!(face).next_id.fetch_add(1, Ordering::SeqCst), - ext_wire_expr: WireExprType { - wire_expr: Resource::get_best_key(res, "", face.id), - }, - }), - }, - res.expr().to_string(), - ), + &face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareToken(UndeclareToken { + id: face_hat!(face.state).next_id.fetch_add(1, Ordering::SeqCst), + ext_wire_expr: WireExprType { + wire_expr: Resource::get_best_key(res, "", face.state.id), + }, + }), + }, + Some(res.clone()), ); } - for res in face_hat!(&mut face) + for res in face_hat!(&mut face.state) .local_tokens .keys() .cloned() @@ -459,57 +458,53 @@ fn propagate_forget_simple_token( if !res.context().matches.iter().any(|m| { m.upgrade().is_some_and(|m| { m.context.is_some() - && (remote_simple_tokens(tables, &m, &face) + && (remote_simple_tokens(tables, &m, &face.state) || remote_linkstatepeer_tokens(tables, &m) || remote_router_tokens(tables, &m)) }) }) { - if let Some(id) = face_hat_mut!(&mut face).local_tokens.remove(&res) { + if let Some(id) = face_hat_mut!(&mut face.state).local_tokens.remove(&res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareToken(UndeclareToken { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + &face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareToken(UndeclareToken { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); - } else if face_hat!(face) + } else if face_hat!(face.state) .remote_interests .values() .any(|i| i.options.tokens() && i.matches(&res) && !i.options.aggregate()) && src_face.map_or(true, |src_face| { src_face.whatami != WhatAmI::Peer - || face.whatami != WhatAmI::Peer - || hat!(tables).failover_brokering(src_face.zid, face.zid) + || face.state.whatami != WhatAmI::Peer + || hat!(tables).failover_brokering(src_face.zid, face.state.zid) }) { // Token has never been declared on this face. // Send an Undeclare with a one shot generated id and a WireExpr ext. send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareToken(UndeclareToken { - id: face_hat!(face).next_id.fetch_add(1, Ordering::SeqCst), - ext_wire_expr: WireExprType { - wire_expr: Resource::get_best_key(&res, "", face.id), - }, - }), - }, - res.expr().to_string(), - ), + &face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareToken(UndeclareToken { + id: face_hat!(face.state).next_id.fetch_add(1, Ordering::SeqCst), + ext_wire_expr: WireExprType { + wire_expr: Resource::get_best_key(&res, "", face.state.id), + }, + }), + }, + Some(res.clone()), ); } } @@ -526,38 +521,32 @@ fn propagate_forget_simple_token_to_peers( && res_hat!(res).router_tokens.len() == 1 && res_hat!(res).router_tokens.contains(&tables.zid) { - for mut face in tables - .faces - .values() - .cloned() - .collect::>>() - { - if face.whatami == WhatAmI::Peer - && face_hat!(face).local_tokens.contains_key(res) + for mut face in tables.faces.values().cloned().collect::>() { + if face.state.whatami == WhatAmI::Peer + && face_hat!(face.state).local_tokens.contains_key(res) && !res.session_ctxs.values().any(|s| { - face.zid != s.face.zid + face.state.zid != s.face.state.zid && s.token - && (s.face.whatami == WhatAmI::Client - || (s.face.whatami == WhatAmI::Peer - && hat!(tables).failover_brokering(s.face.zid, face.zid))) + && (s.face.state.whatami == WhatAmI::Client + || (s.face.state.whatami == WhatAmI::Peer + && hat!(tables) + .failover_brokering(s.face.state.zid, face.state.zid))) }) { - if let Some(id) = face_hat_mut!(&mut face).local_tokens.remove(res) { + if let Some(id) = face_hat_mut!(&mut face.state).local_tokens.remove(res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareToken(UndeclareToken { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + &face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareToken(UndeclareToken { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } } @@ -718,27 +707,25 @@ pub(super) fn undeclare_simple_token( } if simple_tokens.len() == 1 && !router_tokens && !linkstatepeer_tokens { - let mut face = &mut simple_tokens[0]; - if face.whatami != WhatAmI::Client { - if let Some(id) = face_hat_mut!(face).local_tokens.remove(res) { + let face = &mut simple_tokens[0]; + if face.state.whatami != WhatAmI::Client { + if let Some(id) = face_hat_mut!(&mut face.state).local_tokens.remove(res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareToken(UndeclareToken { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareToken(UndeclareToken { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } - for res in face_hat!(face) + for res in face_hat!(face.state) .local_tokens .keys() .cloned() @@ -747,27 +734,25 @@ pub(super) fn undeclare_simple_token( if !res.context().matches.iter().any(|m| { m.upgrade().is_some_and(|m| { m.context.is_some() - && (remote_simple_tokens(tables, &m, face) + && (remote_simple_tokens(tables, &m, &face.state) || remote_linkstatepeer_tokens(tables, &m) || remote_router_tokens(tables, &m)) }) }) { - if let Some(id) = face_hat_mut!(&mut face).local_tokens.remove(&res) { + if let Some(id) = face_hat_mut!(&mut face.state).local_tokens.remove(&res) { send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::UndeclareToken(UndeclareToken { - id, - ext_wire_expr: WireExprType::null(), - }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::UndeclareToken(UndeclareToken { + id, + ext_wire_expr: WireExprType::null(), + }), + }, + Some(res.clone()), ); } } @@ -891,74 +876,73 @@ pub(super) fn token_linkstate_change( send_declare: &mut SendDeclare, ) { if let Some(mut src_face) = tables.get_face(zid).cloned() { - if hat!(tables).router_peers_failover_brokering && src_face.whatami == WhatAmI::Peer { - let to_forget = face_hat!(src_face) + if hat!(tables).router_peers_failover_brokering && src_face.state.whatami == WhatAmI::Peer { + let to_forget = face_hat!(src_face.state) .local_tokens .keys() .filter(|res| { let client_tokens = res .session_ctxs .values() - .any(|ctx| ctx.face.whatami == WhatAmI::Client && ctx.token); + .any(|ctx| ctx.face.state.whatami == WhatAmI::Client && ctx.token); !remote_router_tokens(tables, res) && !client_tokens && !res.session_ctxs.values().any(|ctx| { - ctx.face.whatami == WhatAmI::Peer - && src_face.id != ctx.face.id - && HatTables::failover_brokering_to(links, ctx.face.zid) + ctx.face.state.whatami == WhatAmI::Peer + && src_face.state.id != ctx.face.state.id + && HatTables::failover_brokering_to(links, ctx.face.state.zid) }) }) .cloned() .collect::>>(); for res in to_forget { - if let Some(id) = face_hat_mut!(&mut src_face).local_tokens.remove(&res) { - let wire_expr = Resource::get_best_key(&res, "", src_face.id); + if let Some(id) = face_hat_mut!(&mut src_face.state).local_tokens.remove(&res) { + let wire_expr = Resource::get_best_key(&res, "", src_face.state.id); send_declare( - &src_face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::default(), - body: DeclareBody::UndeclareToken(UndeclareToken { - id, - ext_wire_expr: WireExprType { wire_expr }, - }), - }, - res.expr().to_string(), - ), + &src_face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::UndeclareToken(UndeclareToken { + id, + ext_wire_expr: WireExprType { wire_expr }, + }), + }, + Some(res.clone()), ); } } for mut dst_face in tables.faces.values().cloned() { - if src_face.id != dst_face.id - && HatTables::failover_brokering_to(links, dst_face.zid) + if src_face.state.id != dst_face.state.id + && HatTables::failover_brokering_to(links, dst_face.state.zid) { - for res in face_hat!(src_face).remote_tokens.values() { - if !face_hat!(dst_face).local_tokens.contains_key(res) { - let id = face_hat!(dst_face).next_id.fetch_add(1, Ordering::SeqCst); - face_hat_mut!(&mut dst_face) + for res in face_hat!(src_face.state).remote_tokens.values() { + if !face_hat!(dst_face.state).local_tokens.contains_key(res) { + let id = face_hat!(dst_face.state) + .next_id + .fetch_add(1, Ordering::SeqCst); + face_hat_mut!(&mut dst_face.state) .local_tokens .insert(res.clone(), id); - let push_declaration = push_declaration_profile(tables, &dst_face); - let key_expr = Resource::decl_key(res, &mut dst_face, push_declaration); + let push_declaration = + push_declaration_profile(tables, &dst_face.state); + let key_expr = Resource::decl_key(res, &dst_face, push_declaration); send_declare( - &dst_face.primitives, - RoutingContext::with_expr( - Declare { - interest_id: None, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::default(), - body: DeclareBody::DeclareToken(DeclareToken { - id, - wire_expr: key_expr, - }), - }, - res.expr().to_string(), - ), + &dst_face, + Declare { + interest_id: None, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::default(), + body: DeclareBody::DeclareToken(DeclareToken { + id, + wire_expr: key_expr, + }), + }, + Some(res.clone()), ); } } @@ -985,7 +969,7 @@ fn make_token_id(res: &Arc, face: &mut Arc, mode: InterestM pub(crate) fn declare_token_interest( tables: &mut Tables, - face: &mut Arc, + face: &Face, id: InterestId, res: Option<&mut Arc>, mode: InterestMode, @@ -993,8 +977,8 @@ pub(crate) fn declare_token_interest( send_declare: &mut SendDeclare, ) { if mode.current() - && (face.whatami == WhatAmI::Client - || (face.whatami == WhatAmI::Peer && !hat!(tables).full_net(WhatAmI::Peer))) + && (face.state.whatami == WhatAmI::Client + || (face.state.whatami == WhatAmI::Peer && !hat!(tables).full_net(WhatAmI::Peer))) { let interest_id = Some(id); if let Some(res) = res.as_ref() { @@ -1002,25 +986,26 @@ pub(crate) fn declare_token_interest( if hat!(tables).router_tokens.iter().any(|token| { token.context.is_some() && token.matches(res) - && (remote_simple_tokens(tables, token, face) + && (remote_simple_tokens(tables, token, &face.state) || remote_linkstatepeer_tokens(tables, token) || remote_router_tokens(tables, token)) }) { - let id = make_token_id(res, face, mode); - let wire_expr = - Resource::decl_key(res, face, push_declaration_profile(tables, face)); + let id = make_token_id(res, &mut face.state.clone(), mode); + let wire_expr = Resource::decl_key( + res, + face, + push_declaration_profile(tables, &face.state), + ); send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareToken(DeclareToken { id, wire_expr }), - }, - res.expr().to_string(), - ), + face, + Declare { + interest_id, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareToken(DeclareToken { id, wire_expr }), + }, + Some(res.deref().clone()), ); } } else { @@ -1036,30 +1021,33 @@ pub(crate) fn declare_token_interest( .iter() .any(|r| *r != tables.zid) || token.session_ctxs.values().any(|s| { - s.face.id != face.id + s.face.state.id != face.state.id && s.token - && (s.face.whatami == WhatAmI::Client - || face.whatami == WhatAmI::Client - || (s.face.whatami == WhatAmI::Peer - && hat!(tables) - .failover_brokering(s.face.zid, face.zid))) + && (s.face.state.whatami == WhatAmI::Client + || face.state.whatami == WhatAmI::Client + || (s.face.state.whatami == WhatAmI::Peer + && hat!(tables).failover_brokering( + s.face.state.zid, + face.state.zid, + ))) })) { - let id = make_token_id(token, face, mode); - let wire_expr = - Resource::decl_key(token, face, push_declaration_profile(tables, face)); + let id = make_token_id(token, &mut face.state.clone(), mode); + let wire_expr = Resource::decl_key( + token, + face, + push_declaration_profile(tables, &face.state), + ); send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareToken(DeclareToken { id, wire_expr }), - }, - token.expr().to_string(), - ), + face, + Declare { + interest_id, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareToken(DeclareToken { id, wire_expr }), + }, + Some(token.clone()), ); } } @@ -1077,26 +1065,28 @@ pub(crate) fn declare_token_interest( .any(|r| *r != tables.zid) || token.session_ctxs.values().any(|s| { s.token - && (s.face.whatami != WhatAmI::Peer - || face.whatami != WhatAmI::Peer - || hat!(tables).failover_brokering(s.face.zid, face.zid)) + && (s.face.state.whatami != WhatAmI::Peer + || face.state.whatami != WhatAmI::Peer + || hat!(tables) + .failover_brokering(s.face.state.zid, face.state.zid)) })) { - let id = make_token_id(token, face, mode); - let wire_expr = - Resource::decl_key(token, face, push_declaration_profile(tables, face)); + let id = make_token_id(token, &mut face.state.clone(), mode); + let wire_expr = Resource::decl_key( + token, + face, + push_declaration_profile(tables, &face.state), + ); send_declare( - &face.primitives, - RoutingContext::with_expr( - Declare { - interest_id, - ext_qos: ext::QoSType::DECLARE, - ext_tstamp: None, - ext_nodeid: ext::NodeIdType::DEFAULT, - body: DeclareBody::DeclareToken(DeclareToken { id, wire_expr }), - }, - token.expr().to_string(), - ), + face, + Declare { + interest_id, + ext_qos: ext::QoSType::DECLARE, + ext_tstamp: None, + ext_nodeid: ext::NodeIdType::DEFAULT, + body: DeclareBody::DeclareToken(DeclareToken { id, wire_expr }), + }, + Some(token.clone()), ); } } @@ -1108,23 +1098,29 @@ impl HatTokenTrait for HatCode { fn declare_token( &self, tables: &mut Tables, - face: &mut Arc, + face: &Face, id: TokenId, res: &mut Arc, node_id: NodeId, _interest_id: Option, send_declare: &mut SendDeclare, ) { - match face.whatami { + match face.state.whatami { WhatAmI::Router => { - if let Some(router) = get_router(tables, face, node_id) { - declare_router_token(tables, face, res, router, send_declare) + if let Some(router) = get_router(tables, &face.state, node_id) { + declare_router_token(tables, &mut face.state.clone(), res, router, send_declare) } } WhatAmI::Peer => { if hat!(tables).full_net(WhatAmI::Peer) { - if let Some(peer) = get_peer(tables, face, node_id) { - declare_linkstatepeer_token(tables, face, res, peer, send_declare) + if let Some(peer) = get_peer(tables, &face.state, node_id) { + declare_linkstatepeer_token( + tables, + &mut face.state.clone(), + res, + peer, + send_declare, + ) } } else { declare_simple_token(tables, face, id, res, send_declare) diff --git a/zenoh/src/net/routing/interceptor/access_control.rs b/zenoh/src/net/routing/interceptor/access_control.rs index 61779266e9..71748bc442 100644 --- a/zenoh/src/net/routing/interceptor/access_control.rs +++ b/zenoh/src/net/routing/interceptor/access_control.rs @@ -64,19 +64,19 @@ impl EgressAclEnforcer { cached_permission: Option, action: AclMessage, log_msg: &str, - key_expr: &keyexpr, + key_expr: Option<&keyexpr>, ) -> Permission { match cached_permission { Some(p) => { match p { Permission::Allow => tracing::trace!( - "Using cached result: {} is authorized to {} on {}", + "Using cached result: {} is authorized to {} on {:?}", self.zid(), log_msg, key_expr ), Permission::Deny => tracing::trace!( - "Using cached result: {} is unauthorized to {} on {}", + "Using cached result: {} is unauthorized to {} on {:?}", self.zid(), log_msg, key_expr @@ -84,7 +84,10 @@ impl EgressAclEnforcer { } p } - None => self.action(action, log_msg, key_expr), + None => match key_expr { + Some(ke) => self.action(action, log_msg, ke), + None => Permission::Allow, + }, } } } @@ -102,19 +105,19 @@ impl IngressAclEnforcer { cached_permission: Option, action: AclMessage, log_msg: &str, - key_expr: &keyexpr, + key_expr: Option<&keyexpr>, ) -> Permission { match cached_permission { Some(p) => { match p { Permission::Allow => tracing::trace!( - "Using cached result: {} is authorized to {} on {}", + "Using cached result: {} is authorized to {} on {:?}", self.zid(), log_msg, key_expr ), Permission::Deny => tracing::trace!( - "Using cached result: {} is unauthorized to {} on {}", + "Using cached result: {} is unauthorized to {} on {:?}", self.zid(), log_msg, key_expr @@ -122,7 +125,10 @@ impl IngressAclEnforcer { } p } - None => self.action(action, log_msg, key_expr), + None => match key_expr { + Some(ke) => self.action(action, log_msg, ke), + None => Permission::Deny, + }, } } @@ -381,28 +387,22 @@ impl InterceptorTrait for IngressAclEnforcer { payload: RequestBody::Query(_), .. }) => { - let Some(keyexpr) = ctx.full_keyexpr() else { - return false; - }; if self.cached_result_or_action( cache.map(|c| c.query), AclMessage::Query, "Query (ingress)", - keyexpr, + ctx.full_keyexpr(), ) == Permission::Deny { return false; } } NetworkBodyMut::Response(Response { .. }) => { - let Some(keyexpr) = ctx.full_keyexpr() else { - return false; - }; if self.cached_result_or_action( cache.map(|c| c.reply), AclMessage::Reply, "Reply (ingress)", - keyexpr, + ctx.full_keyexpr(), ) == Permission::Deny { return false; @@ -412,14 +412,11 @@ impl InterceptorTrait for IngressAclEnforcer { payload: PushBody::Put(_), .. }) => { - let Some(keyexpr) = ctx.full_keyexpr() else { - return false; - }; if self.cached_result_or_action( cache.map(|c| c.put), AclMessage::Put, "Put (ingress)", - keyexpr, + ctx.full_keyexpr(), ) == Permission::Deny { return false; @@ -429,14 +426,11 @@ impl InterceptorTrait for IngressAclEnforcer { payload: PushBody::Del(_), .. }) => { - let Some(keyexpr) = ctx.full_keyexpr() else { - return false; - }; if self.cached_result_or_action( cache.map(|c| c.delete), AclMessage::Delete, "Delete (ingress)", - keyexpr, + ctx.full_keyexpr(), ) == Permission::Deny { return false; @@ -446,14 +440,11 @@ impl InterceptorTrait for IngressAclEnforcer { body: DeclareBody::DeclareSubscriber(_), .. }) => { - let Some(keyexpr) = ctx.full_keyexpr() else { - return false; - }; if self.cached_result_or_action( cache.map(|c| c.declare_subscriber), AclMessage::DeclareSubscriber, "Declare Subscriber (ingress)", - keyexpr, + ctx.full_keyexpr(), ) == Permission::Deny { return false; @@ -481,14 +472,11 @@ impl InterceptorTrait for IngressAclEnforcer { body: DeclareBody::DeclareQueryable(_), .. }) => { - let Some(keyexpr) = ctx.full_keyexpr() else { - return false; - }; if self.cached_result_or_action( cache.map(|c| c.declare_queryable), AclMessage::DeclareQueryable, "Declare Queryable (ingress)", - keyexpr, + ctx.full_keyexpr(), ) == Permission::Deny { return false; @@ -516,14 +504,11 @@ impl InterceptorTrait for IngressAclEnforcer { body: DeclareBody::DeclareToken(_), .. }) => { - let Some(keyexpr) = ctx.full_keyexpr() else { - return false; - }; if self.cached_result_or_action( cache.map(|c| c.declare_token), AclMessage::LivelinessToken, "Liveliness Token (ingress)", - keyexpr, + ctx.full_keyexpr(), ) == Permission::Deny { return false; @@ -553,14 +538,11 @@ impl InterceptorTrait for IngressAclEnforcer { options, .. }) if options.tokens() => { - let Some(keyexpr) = ctx.full_keyexpr() else { - return false; - }; if self.cached_result_or_action( cache.map(|c| c.query_token), AclMessage::LivelinessQuery, "Liveliness Query (ingress)", - keyexpr, + ctx.full_keyexpr(), ) == Permission::Deny { return false; @@ -571,14 +553,11 @@ impl InterceptorTrait for IngressAclEnforcer { options, .. }) if options.tokens() => { - let Some(keyexpr) = ctx.full_keyexpr() else { - return false; - }; if self.cached_result_or_action( cache.map(|c| c.declare_liveliness_subscriber), AclMessage::DeclareLivelinessSubscriber, "Declare Liveliness Subscriber (ingress)", - keyexpr, + ctx.full_keyexpr(), ) == Permission::Deny { return false; @@ -669,28 +648,22 @@ impl InterceptorTrait for EgressAclEnforcer { payload: RequestBody::Query(_), .. }) => { - let Some(keyexpr) = ctx.full_keyexpr() else { - return false; - }; if self.cached_result_or_action( cache.map(|c| c.query), AclMessage::Query, "Query (egress)", - keyexpr, + ctx.full_keyexpr(), ) == Permission::Deny { return false; } } NetworkBodyMut::Response(Response { .. }) => { - let Some(keyexpr) = ctx.full_keyexpr() else { - return false; - }; if self.cached_result_or_action( cache.map(|c| c.reply), AclMessage::Reply, "Reply (egress)", - keyexpr, + ctx.full_keyexpr(), ) == Permission::Deny { return false; @@ -700,14 +673,11 @@ impl InterceptorTrait for EgressAclEnforcer { payload: PushBody::Put(_), .. }) => { - let Some(keyexpr) = ctx.full_keyexpr() else { - return false; - }; if self.cached_result_or_action( cache.map(|c| c.put), AclMessage::Put, "Put (egress)", - keyexpr, + ctx.full_keyexpr(), ) == Permission::Deny { return false; @@ -717,14 +687,11 @@ impl InterceptorTrait for EgressAclEnforcer { payload: PushBody::Del(_), .. }) => { - let Some(keyexpr) = ctx.full_keyexpr() else { - return false; - }; if self.cached_result_or_action( cache.map(|c| c.put), AclMessage::Delete, "Delete (egress)", - keyexpr, + ctx.full_keyexpr(), ) == Permission::Deny { return false; @@ -734,14 +701,11 @@ impl InterceptorTrait for EgressAclEnforcer { body: DeclareBody::DeclareSubscriber(_), .. }) => { - let Some(keyexpr) = ctx.full_keyexpr() else { - return false; - }; if self.cached_result_or_action( cache.map(|c| c.declare_subscriber), AclMessage::DeclareSubscriber, "Declare Subscriber (egress)", - keyexpr, + ctx.full_keyexpr(), ) == Permission::Deny { return false; @@ -751,16 +715,13 @@ impl InterceptorTrait for EgressAclEnforcer { body: DeclareBody::UndeclareSubscriber(_), .. }) => { - let Some(keyexpr) = ctx.full_keyexpr() else { - return false; - }; // Undeclaration filtering diverges between ingress and egress: // in egress the keyexpr has to be provided in the RoutingContext if self.cached_result_or_action( cache.map(|c| c.declare_subscriber), AclMessage::DeclareSubscriber, "Undeclare Subscriber (egress)", - keyexpr, + ctx.full_keyexpr(), ) == Permission::Deny { return false; @@ -770,14 +731,11 @@ impl InterceptorTrait for EgressAclEnforcer { body: DeclareBody::DeclareQueryable(_), .. }) => { - let Some(keyexpr) = ctx.full_keyexpr() else { - return false; - }; if self.cached_result_or_action( cache.map(|c| c.declare_queryable), AclMessage::DeclareQueryable, "Declare Queryable (egress)", - keyexpr, + ctx.full_keyexpr(), ) == Permission::Deny { return false; @@ -787,16 +745,13 @@ impl InterceptorTrait for EgressAclEnforcer { body: DeclareBody::UndeclareQueryable(_), .. }) => { - let Some(keyexpr) = ctx.full_keyexpr() else { - return false; - }; // Undeclaration filtering diverges between ingress and egress: // in egress the keyexpr has to be provided in the RoutingContext if self.cached_result_or_action( cache.map(|c| c.declare_queryable), AclMessage::DeclareQueryable, "Undeclare Queryable (egress)", - keyexpr, + ctx.full_keyexpr(), ) == Permission::Deny { return false; @@ -806,14 +761,11 @@ impl InterceptorTrait for EgressAclEnforcer { body: DeclareBody::DeclareToken(_), .. }) => { - let Some(keyexpr) = ctx.full_keyexpr() else { - return false; - }; if self.cached_result_or_action( cache.map(|c| c.declare_token), AclMessage::LivelinessToken, "Liveliness Token (egress)", - keyexpr, + ctx.full_keyexpr(), ) == Permission::Deny { return false; @@ -823,16 +775,13 @@ impl InterceptorTrait for EgressAclEnforcer { body: DeclareBody::UndeclareToken(_), .. }) => { - let Some(keyexpr) = ctx.full_keyexpr() else { - return false; - }; // Undeclaration filtering diverges between ingress and egress: // in egress the keyexpr has to be provided in the RoutingContext if self.cached_result_or_action( cache.map(|c| c.declare_token), AclMessage::LivelinessToken, "Undeclare Liveliness Token (egress)", - keyexpr, + ctx.full_keyexpr(), ) == Permission::Deny { return false; @@ -843,14 +792,11 @@ impl InterceptorTrait for EgressAclEnforcer { options, .. }) if options.tokens() => { - let Some(keyexpr) = ctx.full_keyexpr() else { - return false; - }; if self.cached_result_or_action( cache.map(|c| c.query_token), AclMessage::LivelinessQuery, "Liveliness Query (egress)", - keyexpr, + ctx.full_keyexpr(), ) == Permission::Deny { return false; @@ -861,14 +807,11 @@ impl InterceptorTrait for EgressAclEnforcer { options, .. }) if options.tokens() => { - let Some(keyexpr) = ctx.full_keyexpr() else { - return false; - }; if self.cached_result_or_action( cache.map(|c| c.declare_liveliness_subscriber), AclMessage::DeclareLivelinessSubscriber, "Declare Liveliness Subscriber (egress)", - keyexpr, + ctx.full_keyexpr(), ) == Permission::Deny { return false; @@ -879,18 +822,14 @@ impl InterceptorTrait for EgressAclEnforcer { options, .. }) if options.tokens() => { - let Some(keyexpr) = ctx.full_keyexpr() else { - return false; - }; // Note: options are set for InterestMode::Final for internal use only by egress interceptors. - // InterestMode::Final filtering diverges between ingress and egress: // in egress the keyexpr has to be provided in the RoutingContext if self.cached_result_or_action( cache.map(|c| c.declare_liveliness_subscriber), AclMessage::DeclareLivelinessSubscriber, "Undeclare Liveliness Subscriber (egress)", - keyexpr, + ctx.full_keyexpr(), ) == Permission::Deny { return false; @@ -933,22 +872,24 @@ pub trait AclActionMethods { match policy_enforcer.policy_decision_point(subject.id, self.flow(), action, key_expr) { Ok(Permission::Allow) => { tracing::trace!( - "{} on {} is authorized to {} on {}", + "{} on {} is authorized to {} on {} ({:?})", zid, subject.name, log_msg, - key_expr + key_expr, + self.flow() ); decision = Permission::Allow; break; } Ok(Permission::Deny) => { tracing::trace!( - "{} on {} is unauthorized to {} on {}", + "{} on {} is unauthorized to {} on {} ({:?})", zid, subject.name, log_msg, - key_expr + key_expr, + self.flow() ); decision = Permission::Deny; diff --git a/zenoh/src/net/routing/interceptor/low_pass.rs b/zenoh/src/net/routing/interceptor/low_pass.rs index 8a09743063..cce2a87a39 100644 --- a/zenoh/src/net/routing/interceptor/low_pass.rs +++ b/zenoh/src/net/routing/interceptor/low_pass.rs @@ -411,7 +411,7 @@ impl InterceptorTrait for LowPassInterceptor { fn intercept( &self, - ctx: &mut RoutingContext, + ctx: &mut RoutingContext>, cache: Option<&Box>, ) -> bool { let cache = cache.and_then(|i| i.downcast_ref::()); diff --git a/zenoh/src/net/routing/interceptor/mod.rs b/zenoh/src/net/routing/interceptor/mod.rs index fed7d51991..1a30355d6e 100644 --- a/zenoh/src/net/routing/interceptor/mod.rs +++ b/zenoh/src/net/routing/interceptor/mod.rs @@ -83,6 +83,13 @@ impl From<&LinkAuthId> for InterceptorLinkWrapper { } } +/// Interceptor interface. +/// +/// # Requirements +/// +/// - Implementors SHOULD NOT filter out [`zenoh_protocol::network::ResponseFinal`] messages since +/// the router relies on them to respond to queries that get filtered out; this is because Zenoh +/// returns empty replies when no queryable matching a query exists. pub(crate) trait InterceptorTrait { fn compute_keyexpr_cache(&self, key_expr: &keyexpr) -> Option>; @@ -175,7 +182,7 @@ impl InterceptorTrait for InterceptorsChain { .and_then(|caches| caches.get(idx).map(|k| k.as_ref())) .flatten(); if !interceptor.intercept(ctx, cache) { - tracing::trace!("Msg intercepted!"); + tracing::trace!("Msg {:?} intercepted!", &ctx.msg); return false; } } diff --git a/zenoh/src/net/routing/mod.rs b/zenoh/src/net/routing/mod.rs index 290be7043d..3935bb2da7 100644 --- a/zenoh/src/net/routing/mod.rs +++ b/zenoh/src/net/routing/mod.rs @@ -87,6 +87,16 @@ impl RoutingContext { } } + pub(crate) fn with_prefix(msg: Msg, prefix: Arc) -> Self { + Self { + msg, + inface: OnceCell::new(), + outface: OnceCell::new(), + prefix: OnceCell::from(prefix), + full_expr: OnceCell::new(), + } + } + #[allow(dead_code)] pub(crate) fn inface(&self) -> Option<&Face> { self.inface.get() @@ -96,16 +106,6 @@ impl RoutingContext { pub(crate) fn outface(&self) -> Option<&Face> { self.outface.get() } - - pub(crate) fn with_mut(mut self, f: impl FnOnce(RoutingContext<&mut Msg>) -> R) -> R { - f(RoutingContext { - msg: &mut self.msg, - inface: self.inface, - outface: self.outface, - prefix: self.prefix, - full_expr: self.full_expr, - }) - } } impl RoutingContext> { @@ -121,7 +121,7 @@ impl RoutingContext> { let wire_expr = wire_expr.to_owned(); if self.prefix.get().is_none() { if let Some(prefix) = zread!(face.tables.tables) - .get_sent_mapping(&face.state, &wire_expr.scope, wire_expr.mapping) + .get_sent_mapping(&face.state, wire_expr.scope, wire_expr.mapping) .cloned() { let _ = self.prefix.set(prefix); @@ -135,7 +135,7 @@ impl RoutingContext> { let wire_expr = wire_expr.to_owned(); if self.prefix.get().is_none() { if let Some(prefix) = zread!(face.tables.tables) - .get_mapping(&face.state, &wire_expr.scope, wire_expr.mapping) + .get_mapping(&face.state, wire_expr.scope, wire_expr.mapping) .cloned() { let _ = self.prefix.set(prefix); @@ -152,12 +152,22 @@ impl RoutingContext> { if self.full_expr.get().is_some() { return Some(self.full_expr.get().as_ref().unwrap()); } + + if let Some(prefix) = self.prefix.get() { + let _ = self + .full_expr + .set(prefix.expr().to_string() + self.wire_expr().unwrap().suffix.as_ref()); + return Some(self.full_expr.get().as_ref().unwrap()); + } + + // FIXME(fuzzypixelz): this should likely be removed, alongside outface and inface and prefix() if let Some(prefix) = self.prefix() { let _ = self .full_expr .set(prefix.expr().to_string() + self.wire_expr().unwrap().suffix.as_ref()); return Some(self.full_expr.get().as_ref().unwrap()); } + None } diff --git a/zenoh/src/net/routing/router.rs b/zenoh/src/net/routing/router.rs index b183987da2..02d1531f5b 100644 --- a/zenoh/src/net/routing/router.rs +++ b/zenoh/src/net/routing/router.rs @@ -76,11 +76,12 @@ impl Router { let zid = tables.zid; let fid = tables.face_counter; tables.face_counter += 1; - let newface = tables + let mut face = tables .faces .entry(fid) - .or_insert_with(|| { - FaceState::new( + .or_insert_with(|| Face { + tables: self.tables.clone(), + state: FaceState::new( fid, zid, WhatAmI::Client, @@ -89,27 +90,24 @@ impl Router { primitives.clone(), None, None, + None, ctrl_lock.new_face(), true, - ) + ), }) .clone(); - tracing::debug!("New {}", newface); + tracing::debug!("New {}", face); - let mut face = Face { - tables: self.tables.clone(), - state: newface, - }; let mut declares = vec![]; ctrl_lock - .new_local_face(&mut tables, &self.tables, &mut face, &mut |p, m| { - declares.push((p.clone(), m)) + .new_local_face(&mut tables, &self.tables, &mut face, &mut |p, m, r| { + declares.push((p.clone(), m, r)) }) .unwrap(); drop(tables); drop(ctrl_lock); - for (p, m) in declares { - m.with_mut(|m| p.send_declare(m)); + for (p, mut m, r) in declares { + p.intercept_declare(&mut m, r.as_ref()); } Arc::new(face) } @@ -125,13 +123,15 @@ impl Router { #[cfg(feature = "stats")] let stats = transport.get_stats()?; - let ingress = Arc::new(ArcSwap::new(InterceptorsChain::empty().into())); - let mux = Arc::new(Mux::new(transport.clone(), InterceptorsChain::empty())); - let newface = tables + let ingress = ArcSwap::new(InterceptorsChain::empty().into()); + let egress = ArcSwap::new(InterceptorsChain::empty().into()); + let mux = Arc::new(Mux::new(transport.clone())); + let mut face = tables .faces .entry(fid) - .or_insert_with(|| { - FaceState::new( + .or_insert_with(|| Face { + tables: self.tables.clone(), + state: FaceState::new( fid, zid, whatami, @@ -139,24 +139,18 @@ impl Router { Some(stats), mux.clone(), None, - Some(ingress.clone()), + Some(ingress), + Some(egress), ctrl_lock.new_face(), false, - ) + ), }) .clone(); - newface.set_interceptors_from_factories( + face.state.set_interceptors_from_factories( &tables.interceptors, tables.next_interceptor_version.load(Ordering::SeqCst), ); - tracing::debug!("New {}", newface); - - let mut face = Face { - tables: self.tables.clone(), - state: newface, - }; - - let _ = mux.face.set(Face::downgrade(&face)); + tracing::debug!("New {}", face); let mut declares = vec![]; ctrl_lock.new_transport_unicast_face( @@ -164,15 +158,15 @@ impl Router { &self.tables, &mut face, &transport, - &mut |p, m| declares.push((p.clone(), m)), + &mut |p, m, r| declares.push((p.clone(), m, r)), )?; drop(tables); drop(ctrl_lock); - for (p, m) in declares { - m.with_mut(|m| p.send_declare(m)); + for (p, mut m, r) in declares { + p.intercept_declare(&mut m, r.as_ref()); } - Ok(Arc::new(DeMux::new(face, Some(transport), ingress))) + Ok(Arc::new(DeMux::new(face, Some(transport)))) } pub fn new_transport_multicast(&self, transport: TransportMulticast) -> ZResult<()> { @@ -180,7 +174,8 @@ impl Router { let mut tables = zwrite!(self.tables.tables); let fid = tables.face_counter; tables.face_counter += 1; - let mux = Arc::new(McastMux::new(transport.clone(), InterceptorsChain::empty())); + let mux = Arc::new(McastMux::new(transport.clone())); + let egress = ArcSwap::new(Arc::new(InterceptorsChain::empty())); let face = FaceState::new( fid, ZenohIdProto::from_str("1").unwrap(), @@ -190,6 +185,7 @@ impl Router { mux.clone(), Some(transport), None, + Some(egress), ctrl_lock.new_face(), false, ); @@ -197,10 +193,10 @@ impl Router { &tables.interceptors, tables.next_interceptor_version.load(Ordering::SeqCst), ); - let _ = mux.face.set(Face { + let face = Face { state: face.clone(), tables: self.tables.clone(), - }); + }; tables.mcast_groups.push(face); tables.disable_all_routes(); @@ -216,7 +212,8 @@ impl Router { let mut tables = zwrite!(self.tables.tables); let fid = tables.face_counter; tables.face_counter += 1; - let interceptor = Arc::new(ArcSwap::new(InterceptorsChain::empty().into())); + let ingress = ArcSwap::new(InterceptorsChain::empty().into()); + let egress = ArcSwap::new(InterceptorsChain::empty().into()); let face_state = FaceState::new( fid, peer.zid, @@ -225,7 +222,8 @@ impl Router { Some(transport.get_stats().unwrap()), Arc::new(DummyPrimitives), Some(transport), - Some(interceptor.clone()), + Some(ingress), + Some(egress), ctrl_lock.new_face(), false, ); @@ -242,7 +240,6 @@ impl Router { state: face_state, }, None, - interceptor, ))) } } diff --git a/zenoh/src/net/tests/tables.rs b/zenoh/src/net/tests/tables.rs index bc3491182b..d5c464ee8a 100644 --- a/zenoh/src/net/tests/tables.rs +++ b/zenoh/src/net/tests/tables.rs @@ -34,11 +34,7 @@ use crate::{ net::{ primitives::{DummyPrimitives, EPrimitives, Primitives}, routing::{ - dispatcher::{ - face::{Face, FaceState}, - pubsub::SubscriberInfo, - tables::Tables, - }, + dispatcher::{face::Face, pubsub::SubscriberInfo, tables::Tables}, router::*, RoutingContext, }, @@ -58,16 +54,17 @@ fn base_test() { let tables = router.tables.clone(); let primitives = Arc::new(DummyPrimitives {}); - let face = Arc::downgrade(&router.new_primitives(primitives).state); + let face = router.new_primitives(primitives); + let face = Arc::downgrade(&face); register_expr( &tables, - &mut face.upgrade().unwrap(), + &face.upgrade().unwrap(), 1, &"one/two/three".into(), ); register_expr( &tables, - &mut face.upgrade().unwrap(), + &face.upgrade().unwrap(), 2, &"one/deux/trois".into(), ); @@ -77,12 +74,12 @@ fn base_test() { declare_subscription( zlock!(tables.ctrl_lock).as_ref(), &tables, - &mut face.upgrade().unwrap(), + &face.upgrade().unwrap(), 0, &WireExpr::from(1).with_suffix("four/five"), &sub_info, NodeId::default(), - &mut |p, m| m.with_mut(|m| p.send_declare(m)), + &mut |p, mut m, r| p.intercept_declare(&mut m, r.as_ref()), ); Tables::print(&zread!(tables.tables)); @@ -153,11 +150,12 @@ fn match_test() { let tables = router.tables.clone(); let primitives = Arc::new(DummyPrimitives {}); - let face = Arc::downgrade(&router.new_primitives(primitives).state); + let face = router.new_primitives(primitives); + let face = Arc::downgrade(&face); for (i, key_expr) in key_exprs.iter().enumerate() { register_expr( &tables, - &mut face.upgrade().unwrap(), + &face.upgrade().unwrap(), i.try_into().unwrap(), &(*key_expr).into(), ); @@ -165,15 +163,15 @@ fn match_test() { for key_expr1 in key_exprs.iter() { let res_matches = Resource::get_matches(&zread!(tables.tables), key_expr1); - dbg!(res_matches.len()); + res_matches.len(); for key_expr2 in key_exprs.iter() { if res_matches .iter() .any(|m| m.upgrade().unwrap().expr() == key_expr2.as_str()) { - assert!(dbg!(dbg!(key_expr1).intersects(dbg!(key_expr2)))); + assert!(key_expr1.intersects(key_expr2)); } else { - assert!(!dbg!(dbg!(key_expr1).intersects(dbg!(key_expr2)))); + assert!(!key_expr1.intersects(key_expr2)); } } } @@ -199,12 +197,12 @@ fn multisub_test() { declare_subscription( zlock!(tables.ctrl_lock).as_ref(), &tables, - &mut face0.state.clone(), + face0, 0, &"sub".into(), &sub_info, NodeId::default(), - &mut |p, m| m.with_mut(|m| p.send_declare(m)), + &mut |p, mut m, r| p.intercept_declare(&mut m, r.as_ref()), ); let optres = Resource::get_resource(zread!(tables.tables)._get_root(), "sub") .map(|res| Arc::downgrade(&res)); @@ -215,12 +213,12 @@ fn multisub_test() { declare_subscription( zlock!(tables.ctrl_lock).as_ref(), &tables, - &mut face0.state.clone(), + face0, 1, &"sub".into(), &sub_info, NodeId::default(), - &mut |p, m| m.with_mut(|m| p.send_declare(m)), + &mut |p, mut m, r| p.intercept_declare(&mut m, r.as_ref()), ); assert!(res.upgrade().is_some()); @@ -231,7 +229,7 @@ fn multisub_test() { 0, &WireExpr::empty(), NodeId::default(), - &mut |p, m| m.with_mut(|m| p.send_declare(m)), + &mut |p, mut m, r| p.intercept_declare(&mut m, r.as_ref()), ); assert!(res.upgrade().is_some()); @@ -242,7 +240,7 @@ fn multisub_test() { 1, &WireExpr::empty(), NodeId::default(), - &mut |p, m| m.with_mut(|m| p.send_declare(m)), + &mut |p, mut m, r| p.intercept_declare(&mut m, r.as_ref()), ); assert!(res.upgrade().is_none()); @@ -265,26 +263,21 @@ async fn clean_test() { let face0 = &router.new_primitives(primitives); // -------------- - register_expr(&tables, &mut face0.state.clone(), 1, &"todrop1".into()); + register_expr(&tables, face0, 1, &"todrop1".into()); let optres1 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop1") .map(|res| Arc::downgrade(&res)); assert!(optres1.is_some()); let res1 = optres1.unwrap(); assert!(res1.upgrade().is_some()); - register_expr( - &tables, - &mut face0.state.clone(), - 2, - &"todrop1/todrop11".into(), - ); + register_expr(&tables, face0, 2, &"todrop1/todrop11".into()); let optres2 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop1/todrop11") .map(|res| Arc::downgrade(&res)); assert!(optres2.is_some()); let res2 = optres2.unwrap(); assert!(res2.upgrade().is_some()); - register_expr(&tables, &mut face0.state.clone(), 3, &"**".into()); + register_expr(&tables, face0, 3, &"**".into()); let optres3 = Resource::get_resource(zread!(tables.tables)._get_root(), "**") .map(|res| Arc::downgrade(&res)); assert!(optres3.is_some()); @@ -307,7 +300,7 @@ async fn clean_test() { assert!(res3.upgrade().is_none()); // -------------- - register_expr(&tables, &mut face0.state.clone(), 1, &"todrop1".into()); + register_expr(&tables, face0, 1, &"todrop1".into()); let optres1 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop1") .map(|res| Arc::downgrade(&res)); assert!(optres1.is_some()); @@ -319,12 +312,12 @@ async fn clean_test() { declare_subscription( zlock!(tables.ctrl_lock).as_ref(), &tables, - &mut face0.state.clone(), + face0, 0, &"todrop1/todrop11".into(), &sub_info, NodeId::default(), - &mut |p, m| m.with_mut(|m| p.send_declare(m)), + &mut |p, mut m, r| p.intercept_declare(&mut m, r.as_ref()), ); let optres2 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop1/todrop11") .map(|res| Arc::downgrade(&res)); @@ -335,12 +328,12 @@ async fn clean_test() { declare_subscription( zlock!(tables.ctrl_lock).as_ref(), &tables, - &mut face0.state.clone(), + face0, 1, &WireExpr::from(1).with_suffix("/todrop12"), &sub_info, NodeId::default(), - &mut |p, m| m.with_mut(|m| p.send_declare(m)), + &mut |p, mut m, r| p.intercept_declare(&mut m, r.as_ref()), ); let optres3 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop1/todrop12") .map(|res| Arc::downgrade(&res)); @@ -356,7 +349,7 @@ async fn clean_test() { 1, &WireExpr::empty(), NodeId::default(), - &mut |p, m| m.with_mut(|m| p.send_declare(m)), + &mut |p, mut m, r| p.intercept_declare(&mut m, r.as_ref()), ); println!("COUNT2: {}", res3.strong_count()); @@ -372,7 +365,7 @@ async fn clean_test() { 0, &WireExpr::empty(), NodeId::default(), - &mut |p, m| m.with_mut(|m| p.send_declare(m)), + &mut |p, mut m, r| p.intercept_declare(&mut m, r.as_ref()), ); assert!(res1.upgrade().is_some()); assert!(res2.upgrade().is_none()); @@ -384,16 +377,16 @@ async fn clean_test() { assert!(res3.upgrade().is_none()); // -------------- - register_expr(&tables, &mut face0.state.clone(), 2, &"todrop3".into()); + register_expr(&tables, face0, 2, &"todrop3".into()); declare_subscription( zlock!(tables.ctrl_lock).as_ref(), &tables, - &mut face0.state.clone(), + face0, 2, &"todrop3".into(), &sub_info, NodeId::default(), - &mut |p, m| m.with_mut(|m| p.send_declare(m)), + &mut |p, mut m, r| p.intercept_declare(&mut m, r.as_ref()), ); let optres1 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop3") .map(|res| Arc::downgrade(&res)); @@ -408,7 +401,7 @@ async fn clean_test() { 2, &WireExpr::empty(), NodeId::default(), - &mut |p, m| m.with_mut(|m| p.send_declare(m)), + &mut |p, mut m, r| p.intercept_declare(&mut m, r.as_ref()), ); assert!(res1.upgrade().is_some()); @@ -416,27 +409,27 @@ async fn clean_test() { assert!(res1.upgrade().is_none()); // -------------- - register_expr(&tables, &mut face0.state.clone(), 3, &"todrop4".into()); - register_expr(&tables, &mut face0.state.clone(), 4, &"todrop5".into()); + register_expr(&tables, face0, 3, &"todrop4".into()); + register_expr(&tables, face0, 4, &"todrop5".into()); declare_subscription( zlock!(tables.ctrl_lock).as_ref(), &tables, - &mut face0.state.clone(), + face0, 3, &"todrop5".into(), &sub_info, NodeId::default(), - &mut |p, m| m.with_mut(|m| p.send_declare(m)), + &mut |p, mut m, r| p.intercept_declare(&mut m, r.as_ref()), ); declare_subscription( zlock!(tables.ctrl_lock).as_ref(), &tables, - &mut face0.state.clone(), + face0, 4, &"todrop6".into(), &sub_info, NodeId::default(), - &mut |p, m| m.with_mut(|m| p.send_declare(m)), + &mut |p, mut m, r| p.intercept_declare(&mut m, r.as_ref()), ); let optres1 = Resource::get_resource(zread!(tables.tables)._get_root(), "todrop4") @@ -596,10 +589,11 @@ fn client_test() { let sub_info = SubscriberInfo; let primitives0 = Arc::new(ClientPrimitives::new()); - let face0 = Arc::downgrade(&router.new_primitives(primitives0.clone()).state); + let face = router.new_primitives(primitives0.clone()); + let face0 = Arc::downgrade(&face); register_expr( &tables, - &mut face0.upgrade().unwrap(), + &face0.upgrade().unwrap(), 11, &"test/client".into(), ); @@ -619,16 +613,16 @@ fn client_test() { declare_subscription( zlock!(tables.ctrl_lock).as_ref(), &tables, - &mut face0.upgrade().unwrap(), + &face0.upgrade().unwrap(), 0, &WireExpr::from(11).with_suffix("/**"), &sub_info, NodeId::default(), - &mut |p, m| m.with_mut(|m| p.send_declare(m)), + &mut |p, mut m, r| p.intercept_declare(&mut m, r.as_ref()), ); register_expr( &tables, - &mut face0.upgrade().unwrap(), + &face0.upgrade().unwrap(), 12, &WireExpr::from(11).with_suffix("/z1_pub1"), ); @@ -647,10 +641,11 @@ fn client_test() { ); let primitives1 = Arc::new(ClientPrimitives::new()); - let face1 = Arc::downgrade(&router.new_primitives(primitives1.clone()).state); + let face = router.new_primitives(primitives1.clone()); + let face1 = Arc::downgrade(&face); register_expr( &tables, - &mut face1.upgrade().unwrap(), + &face1.upgrade().unwrap(), 21, &"test/client".into(), ); @@ -670,16 +665,16 @@ fn client_test() { declare_subscription( zlock!(tables.ctrl_lock).as_ref(), &tables, - &mut face1.upgrade().unwrap(), + &face1.upgrade().unwrap(), 0, &WireExpr::from(21).with_suffix("/**"), &sub_info, NodeId::default(), - &mut |p, m| m.with_mut(|m| p.send_declare(m)), + &mut |p, mut m, r| p.intercept_declare(&mut m, r.as_ref()), ); register_expr( &tables, - &mut face1.upgrade().unwrap(), + &face1.upgrade().unwrap(), 22, &WireExpr::from(21).with_suffix("/z2_pub1"), ); @@ -698,10 +693,11 @@ fn client_test() { ); let primitives2 = Arc::new(ClientPrimitives::new()); - let face2 = Arc::downgrade(&router.new_primitives(primitives2.clone()).state); + let face = router.new_primitives(primitives2.clone()); + let face2 = Arc::downgrade(&face); register_expr( &tables, - &mut face2.upgrade().unwrap(), + &face2.upgrade().unwrap(), 31, &"test/client".into(), ); @@ -721,22 +717,22 @@ fn client_test() { declare_subscription( zlock!(tables.ctrl_lock).as_ref(), &tables, - &mut face2.upgrade().unwrap(), + &face2.upgrade().unwrap(), 0, &WireExpr::from(31).with_suffix("/**"), &sub_info, NodeId::default(), - &mut |p, m| m.with_mut(|m| p.send_declare(m)), + &mut |p, mut m, r| p.intercept_declare(&mut m, r.as_ref()), ); primitives0.clear_data(); primitives1.clear_data(); primitives2.clear_data(); - let route_dummy_data = |face: &Weak, wire_expr| { + let route_dummy_data = |face: &Weak, wire_expr| { route_data( &tables, - &face.upgrade().unwrap(), + &face.upgrade().unwrap().state, &mut Push { wire_expr, ext_qos: ext::QoSType::DEFAULT, @@ -858,7 +854,7 @@ fn get_best_key_test() { let root = zread!(router.tables.tables)._get_root().clone(); let register_expr = |face: &Face, id: ExprId, expr: &str| { - register_expr(&router.tables, &mut face.state.clone(), id, &expr.into()); + register_expr(&router.tables, face, id, &expr.into()); }; let get_best_key = |resource, suffix, face: &Face| { Resource::get_resource(&root, resource) @@ -910,7 +906,7 @@ fn big_key_expr() { let root = zread!(router.tables.tables)._get_root().clone(); let key_expr = KeyExpr::new(vec!["a/"; 10000].concat() + "a").unwrap(); let wire_expr = WireExpr::from(&**key_expr); - register_expr(&router.tables, &mut face.state.clone(), 1, &wire_expr); + register_expr(&router.tables, &face, 1, &wire_expr); let res = Resource::get_resource(&root, &key_expr).unwrap(); root.get_best_key(&key_expr, face.state.id); res.get_best_key("/a", face.state.id + 1);