use std::any::Any;
use crate::chaos::state_handle::{StateHandle, Timeline};
use crate::network::SimNetworkProvider;
use crate::providers::{SimProviders, SimRandomProvider, SimTimeProvider};
use crate::storage::SimStorageProvider;
use moonpool_core::{Providers, TimeProvider, TokioTaskProvider};
use super::topology::WorkloadTopology;
pub struct SimContext {
providers: SimProviders,
topology: WorkloadTopology,
state: StateHandle,
}
impl SimContext {
pub fn new(providers: SimProviders, topology: WorkloadTopology, state: StateHandle) -> Self {
Self {
providers,
topology,
state,
}
}
pub fn providers(&self) -> &SimProviders {
&self.providers
}
pub fn network(&self) -> &SimNetworkProvider {
self.providers.network()
}
pub fn time(&self) -> &SimTimeProvider {
self.providers.time()
}
pub fn task(&self) -> &TokioTaskProvider {
self.providers.task()
}
pub fn random(&self) -> &SimRandomProvider {
self.providers.random()
}
pub fn storage(&self) -> &SimStorageProvider {
self.providers.storage()
}
pub fn my_ip(&self) -> &str {
&self.topology.my_ip
}
pub fn client_id(&self) -> usize {
self.topology.client_id
}
pub fn client_count(&self) -> usize {
self.topology.client_count
}
pub fn peer(&self, name: &str) -> Option<String> {
self.topology.peer_by_name(name)
}
pub fn peers(&self) -> Vec<(String, String)> {
self.topology
.peer_names
.iter()
.zip(self.topology.peer_ips.iter())
.map(|(name, ip)| (name.clone(), ip.clone()))
.collect()
}
pub fn shutdown(&self) -> &tokio_util::sync::CancellationToken {
&self.topology.shutdown_signal
}
pub fn topology(&self) -> &WorkloadTopology {
&self.topology
}
pub fn state(&self) -> &StateHandle {
&self.state
}
pub fn emit<T: Any + 'static>(&self, key: &str, event: T) {
let time_ms = self.time().now().as_millis() as u64;
let source = self.my_ip();
self.state.emit_raw(key, event, time_ms, source);
}
pub fn timeline<T: Any + 'static>(&self, key: &str) -> Option<Timeline<T>> {
self.state.timeline(key)
}
}