mod bandwidth;
mod latency;
use std::sync::Arc;
pub use bandwidth::BandwidthConfig;
use crate::GLOBAL_POOL;
use crate::Jiffies;
use crate::Rank;
use crate::events::Event;
use crate::events::NetworkFsm;
use crate::events::RankHandlerEvent;
use crate::events::TimedEvent;
use crate::network::bandwidth::Bandwidth;
use crate::network::latency::Latency;
use crate::random::Randomizer;
use crate::random::Seed;
use crate::topology::Topology;
pub(crate) enum NetworkDecision {
Keep(TimedEvent),
Ready(RankHandlerEvent),
}
pub(crate) struct Network {
bandwidth: Bandwidth,
latency: Latency,
}
impl Network {
pub(crate) fn new(
seed: Seed,
bandwidth_type: BandwidthConfig,
topology: Arc<Topology>,
) -> Self {
Self {
latency: Latency::new(Randomizer::new(seed), topology.clone()),
bandwidth: Bandwidth::new(bandwidth_type, topology.list_pool(GLOBAL_POOL).len()),
}
}
}
impl Network {
pub(crate) fn compute_latency(&mut self, source: Rank, target: Rank) -> Jiffies {
self.latency.random_latency(source, target)
}
}
impl Network {
pub(crate) fn decide(
&mut self,
invocation_time: Jiffies,
mut event: RankHandlerEvent,
) -> NetworkDecision {
match &mut event {
RankHandlerEvent::Network {
target,
message,
fsm,
..
} => match fsm {
NetworkFsm::KeepLatency => {
match self
.bandwidth
.try_pass(message.virtual_size(), *target, invocation_time)
{
None => NetworkDecision::Ready(event),
Some(additional_latency) => {
*fsm = NetworkFsm::KeepBandwidth;
NetworkDecision::Keep(TimedEvent {
invocation_time: invocation_time + additional_latency,
event: Event::Handler(event),
})
}
}
}
NetworkFsm::KeepBandwidth => {
self.bandwidth.add_passed(message.virtual_size(), *target);
NetworkDecision::Ready(event)
}
},
_ => unreachable!(),
}
}
}