SimWorld

Struct SimWorld 

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

The central simulation coordinator that manages time and event processing.

SimWorld owns all mutable simulation state and provides the main interface for scheduling events and advancing simulation time. It uses a centralized ownership model with handle-based access to avoid borrow checker conflicts.

Implementations§

Source§

impl SimWorld

Source

pub fn new() -> Self

Creates a new simulation world with default network configuration.

Uses default seed (0) for reproducible testing. For custom seeds, use SimWorld::new_with_seed.

Source

pub fn new_with_seed(seed: u64) -> Self

Creates a new simulation world with a specific seed for deterministic randomness.

This method ensures clean thread-local RNG state by resetting before setting the seed, making it safe for consecutive simulations on the same thread.

§Parameters
  • seed - The seed value for deterministic randomness
Source

pub fn new_with_network_config(network_config: NetworkConfiguration) -> Self

Creates a new simulation world with custom network configuration.

Source

pub fn new_with_network_config_and_seed( network_config: NetworkConfiguration, seed: u64, ) -> Self

Creates a new simulation world with both custom network configuration and seed.

§Parameters
  • network_config - Network configuration for latency and fault simulation
  • seed - The seed value for deterministic randomness
Source

pub fn step(&mut self) -> bool

Processes the next scheduled event and advances time.

Returns true if more events are available for processing, false if this was the last event or if no events are available.

Source

pub fn run_until_empty(&mut self)

Processes all scheduled events until the queue is empty or only infrastructure events remain.

This method processes all workload-related events but stops early if only infrastructure events (like connection restoration) remain. This prevents infinite loops where infrastructure events keep the simulation running indefinitely after workloads complete.

Source

pub fn current_time(&self) -> Duration

Returns the current simulation time.

Source

pub fn now(&self) -> Duration

Returns the exact simulation time (equivalent to FDB’s now()).

This is the canonical simulation time used for scheduling events. Use this for precise time comparisons and scheduling.

Source

pub fn timer(&self) -> Duration

Returns the drifted timer time (equivalent to FDB’s timer()).

The timer can be up to clock_drift_max (default 100ms) ahead of now(). This simulates real-world clock drift between processes, which is important for testing time-sensitive code like:

  • Timeout handling
  • Lease expiration
  • Distributed consensus (leader election)
  • Cache invalidation
  • Heartbeat detection

FDB formula: timerTime += random01() * (time + 0.1 - timerTime) / 2.0

FDB ref: sim2.actor.cpp:1058-1064

Source

pub fn schedule_event(&self, event: Event, delay: Duration)

Schedules an event to execute after the specified delay from the current time.

Source

pub fn schedule_event_at(&self, event: Event, time: Duration)

Schedules an event to execute at the specified absolute time.

Source

pub fn downgrade(&self) -> WeakSimWorld

Creates a weak reference to this simulation world.

Weak references can be used to access the simulation without preventing it from being dropped, enabling handle-based access patterns.

Source

pub fn has_pending_events(&self) -> bool

Returns true if there are events waiting to be processed.

Source

pub fn pending_event_count(&self) -> usize

Returns the number of events waiting to be processed.

Source

pub fn network_provider(&self) -> SimNetworkProvider

Create a network provider for this simulation

Source

pub fn time_provider(&self) -> SimTimeProvider

Create a time provider for this simulation

Source

pub fn task_provider(&self) -> TokioTaskProvider

Create a task provider for this simulation

Source

pub fn with_network_config<F, R>(&self, f: F) -> R
where F: FnOnce(&NetworkConfiguration) -> R,

Access network configuration for latency calculations using thread-local RNG.

This method provides access to the network configuration for calculating latencies and other network parameters. Random values should be generated using the thread-local RNG functions like sim_random().

Access the network configuration for this simulation.

Source

pub fn sleep(&self, duration: Duration) -> SleepFuture

Sleep for the specified duration in simulation time.

Returns a future that will complete when the simulation time has advanced by the specified duration.

Source

pub fn assertion_results(&self) -> HashMap<String, AssertionStats>

Get current assertion results for all tracked assertions.

Source

pub fn reset_assertion_results(&self)

Reset assertion statistics to empty state.

Source

pub fn extract_metrics(&self) -> SimulationMetrics

Extract simulation metrics for reporting.

Source

pub fn should_clog_write(&self, connection_id: ConnectionId) -> bool

Check if a write should be clogged based on probability

Source

pub fn clog_write(&self, connection_id: ConnectionId)

Clog a connection’s write operations

Source

pub fn is_write_clogged(&self, connection_id: ConnectionId) -> bool

Check if a connection’s writes are currently clogged

Source

pub fn register_clog_waker(&self, connection_id: ConnectionId, waker: Waker)

Register a waker for when write clog clears

Source

pub fn should_clog_read(&self, connection_id: ConnectionId) -> bool

Check if a read should be clogged based on probability

Source

pub fn clog_read(&self, connection_id: ConnectionId)

Clog a connection’s read operations

Source

pub fn is_read_clogged(&self, connection_id: ConnectionId) -> bool

Check if a connection’s reads are currently clogged

Source

pub fn register_read_clog_waker( &self, connection_id: ConnectionId, waker: Waker, )

Register a waker for when read clog clears

Source

pub fn clear_expired_clogs(&self)

Clear expired clogs and wake pending tasks

Source

pub fn cut_connection(&self, connection_id: ConnectionId, duration: Duration)

Temporarily cut a connection for the specified duration.

Unlike close_connection, a cut connection will be automatically restored after the duration expires. This simulates temporary network outages where the underlying connection remains but is temporarily unavailable.

During a cut:

  • poll_read returns Poll::Pending (waits for restore)
  • poll_write returns Poll::Pending (waits for restore)
  • Buffered data is preserved
Source

pub fn is_connection_cut(&self, connection_id: ConnectionId) -> bool

Check if a connection is temporarily cut.

A cut connection is temporarily unavailable but will be restored. This is different from is_connection_closed which indicates permanent closure.

Source

pub fn restore_connection(&self, connection_id: ConnectionId)

Restore a cut connection immediately.

This cancels the cut state and wakes any tasks waiting for restoration.

Source

pub fn register_cut_waker(&self, connection_id: ConnectionId, waker: Waker)

Register a waker for when a cut connection is restored.

Source

pub fn send_buffer_capacity(&self, connection_id: ConnectionId) -> usize

Get the send buffer capacity for a connection.

Source

pub fn send_buffer_used(&self, connection_id: ConnectionId) -> usize

Get the current send buffer usage for a connection.

Source

pub fn available_send_buffer(&self, connection_id: ConnectionId) -> usize

Get the available send buffer space for a connection.

Source

pub fn register_send_buffer_waker( &self, connection_id: ConnectionId, waker: Waker, )

Register a waker for when send buffer space becomes available.

Source

pub fn get_pair_latency(&self, src: IpAddr, dst: IpAddr) -> Option<Duration>

Get the base latency for a connection pair. Returns the latency if already set, otherwise None.

Source

pub fn set_pair_latency_if_not_set( &self, src: IpAddr, dst: IpAddr, latency: Duration, ) -> Duration

Set the base latency for a connection pair if not already set. Returns the latency (existing or newly set).

Source

pub fn get_connection_base_latency( &self, connection_id: ConnectionId, ) -> Duration

Get the base latency for a connection based on its IP pair. If not set, samples from config and sets it.

Source

pub fn get_send_delay(&self, connection_id: ConnectionId) -> Option<Duration>

Get the send delay for a connection. Returns the per-connection override if set, otherwise None.

Source

pub fn get_recv_delay(&self, connection_id: ConnectionId) -> Option<Duration>

Get the receive delay for a connection. Returns the per-connection override if set, otherwise None.

Source

pub fn set_asymmetric_delays( &self, connection_id: ConnectionId, send_delay: Option<Duration>, recv_delay: Option<Duration>, )

Set asymmetric delays for a connection. If a delay is None, the global configuration is used instead.

Source

pub fn is_connection_closed(&self, connection_id: ConnectionId) -> bool

Check if a connection is permanently closed

Source

pub fn close_connection(&self, connection_id: ConnectionId)

Close a connection gracefully (FIN semantics).

The peer will receive EOF on read operations.

Source

pub fn close_connection_abort(&self, connection_id: ConnectionId)

Close a connection abruptly (RST semantics).

The peer will receive ECONNRESET on both read and write operations.

Source

pub fn get_close_reason(&self, connection_id: ConnectionId) -> CloseReason

Get the close reason for a connection.

Source

pub fn close_connection_asymmetric( &self, connection_id: ConnectionId, close_send: bool, close_recv: bool, )

Close connection asymmetrically (FDB rollRandomClose pattern)

Source

pub fn roll_random_close(&self, connection_id: ConnectionId) -> Option<bool>

Roll random close chaos injection (FDB rollRandomClose pattern)

Source

pub fn is_send_closed(&self, connection_id: ConnectionId) -> bool

Check if a connection’s send side is closed

Source

pub fn is_recv_closed(&self, connection_id: ConnectionId) -> bool

Check if a connection’s receive side is closed

Source

pub fn simulate_peer_crash( &self, connection_id: ConnectionId, error_delay: Duration, )

Simulate a peer crash on a connection.

This puts the connection in a half-open state where:

  • The local side still thinks it’s connected
  • Writes succeed but data is silently discarded (peer is gone)
  • Reads block waiting for data that will never come
  • After error_delay, both read and write return ECONNRESET

This simulates real-world scenarios where a remote peer crashes or becomes unreachable, but the local TCP stack hasn’t detected it yet.

Source

pub fn is_half_open(&self, connection_id: ConnectionId) -> bool

Check if a connection is in half-open state

Source

pub fn should_half_open_error(&self, connection_id: ConnectionId) -> bool

Check if a half-open connection should return errors now

Source

pub fn partition_pair( &self, from_ip: IpAddr, to_ip: IpAddr, duration: Duration, ) -> SimulationResult<()>

Partition communication between two IP addresses for a specified duration

Source

pub fn partition_send_from( &self, ip: IpAddr, duration: Duration, ) -> SimulationResult<()>

Block all outgoing communication from an IP address

Source

pub fn partition_recv_to( &self, ip: IpAddr, duration: Duration, ) -> SimulationResult<()>

Block all incoming communication to an IP address

Source

pub fn restore_partition( &self, from_ip: IpAddr, to_ip: IpAddr, ) -> SimulationResult<()>

Immediately restore communication between two IP addresses

Source

pub fn is_partitioned( &self, from_ip: IpAddr, to_ip: IpAddr, ) -> SimulationResult<bool>

Check if communication between two IP addresses is currently partitioned

Trait Implementations§

Source§

impl Debug for SimWorld

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for SimWorld

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

§

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

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

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

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

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

§

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

Mutably borrows from an owned value. Read more
§

impl<T> From<T> for T

§

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
§

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

§

fn into(self) -> U

Calls U::from(self).

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

§

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

§

type Error = Infallible

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

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

Performs the conversion.
§

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

§

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

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

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