Skip to main content

FloodSubRouter

Struct FloodSubRouter 

Source
pub struct FloodSubRouter { /* private fields */ }
Expand description

Topic-based message flooding router.

§Responsibilities

  1. Maintain per-peer topic subscriptions.
  2. Deduplicate messages using a bounded, TTL-based ID cache.
  3. Track which peers have already received a given message to prevent loops.
  4. Compute forward sets excluding the origin peer and previously-forwarded peers.

§Thread safety

FloodSubRouter is not Send + Sync by default; callers should wrap it in a Mutex or RwLock when sharing across threads.

Implementations§

Source§

impl FloodSubRouter

Source

pub fn new(config: RouterConfig) -> Self

Create a new router with the supplied configuration.

Source

pub fn subscribe(&mut self, peer_id: &str, topic: &FloodTopic, now: u64) -> bool

Subscribe peer_id to topic.

Returns true if this was a new subscription, false if the peer was already subscribed to this topic.

The subscription is rejected (returns false) when either:

  • the per-topic peer limit (max_peers_per_topic) would be exceeded, or
  • the global topic limit (max_topics) would be exceeded by a new topic.
Source

pub fn unsubscribe(&mut self, peer_id: &str, topic: &FloodTopic) -> bool

Unsubscribe peer_id from topic.

Returns true if the subscription existed and was removed.

Source

pub fn peers_for_topic(&self, topic: &FloodTopic) -> Vec<String>

Return all peer IDs subscribed to topic.

Source

pub fn topics_for_peer(&self, peer_id: &str) -> Vec<FloodTopic>

Return all topics to which peer_id is subscribed.

Source

pub fn route(&mut self, msg: &FloodMessage, now: u64) -> ForwardDecision

Decide how to forward msg and update all internal state accordingly.

§Decision logic (in order)
  1. If msg.id is already in the dedup cache → Drop (duplicate).
  2. If msg.ttl <= config.min_ttlDrop (TTL exhausted).
  3. If no peer is subscribed to msg.topicDrop (no subscribers).
  4. Insert msg.id into the dedup cache with now as the timestamp.
  5. Build the candidate forward set: all subscribers except the origin peer and peers already recorded in forwarded_to[msg.id].
  6. Record the candidate set in forwarded_to.
  7. If the candidate set is empty and the origin is the only subscriber → Loopback.
  8. If the candidate set is empty (all already forwarded) → Drop.
  9. Otherwise → Forward { to_peers }.
Source

pub fn mark_forwarded(&mut self, id: &FloodMessageId, peer_id: &str)

Record that msg_id was manually forwarded to peer_id.

Useful when the caller forwards a message outside of route and wants to keep the loop-prevention state consistent.

Source

pub fn expire_cache(&mut self, now: u64)

Evict all dedup-cache entries older than config.dedup_window_secs.

Should be called periodically (e.g. every 10–30 seconds) to bound memory consumption.

Source

pub fn stats(&self) -> &FsrRouterStats

Return a reference to the current operational statistics.

Source

pub fn compute_message_id( payload: &[u8], topic: &FloodTopic, peer_id: &str, now: u64, ) -> FloodMessageId

Compute a FloodMessageId from payload, topic, peer_id, and a Unix-epoch timestamp.

The ID is produced by running FNV-1a over all inputs concatenated in a deterministic order, then taking two sequential hashes to fill 16 bytes.

Source

pub fn cache_full(&self) -> bool

Return true when the dedup cache is at capacity.

Source

pub fn forwarded_count(&self, id: &FloodMessageId) -> usize

Return the number of peers that have already been sent id.

Source

pub fn is_subscribed(&self, peer_id: &str, topic: &FloodTopic) -> bool

Return true if peer_id is subscribed to topic.

Source

pub fn subscription( &self, peer_id: &str, topic: &FloodTopic, ) -> Option<&SubscriptionRecord>

Return the SubscriptionRecord for peer_id on topic, if any.

Source

pub fn subscription_count(&self) -> usize

Return the total number of active subscriptions.

Source

pub fn all_subscriptions(&self) -> impl Iterator<Item = &SubscriptionRecord>

Return an iterator over all active SubscriptionRecords.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Allocation for T
where T: RefUnwindSafe + Send + Sync,

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

Source§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

Source§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

Source§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more