utils.rs

Overview

This file provides utility wrappers around the core Transport and Socket traits to simulate network conditions such as message delay and message drop (loss). These wrappers enable the testing and simulation of unreliable network behaviors by introducing probabilistic delays or drops to message sending operations. The utilities are implemented as decorator-like structures that wrap existing transports and sockets, enhancing their behavior without modifying underlying implementations.

The key abstractions are:

By applying these wrappers, developers can test how their distributed protocols handle network latency and packet loss scenarios.


Detailed Explanation of Components

Traits and Type Aliases

DelayMillisDist

pub trait DelayMillisDist: Distribution<f32> + Send + Sync + Clone + 'static {}

Structs and Implementations

TransportWithDelay<D>

struct TransportWithDelay<D: Distribution<f32> + Send + Sync + 'static> {
    delay_secs: D,
    transport: Box<dyn Transport>,
}
Implementation of Transport for TransportWithDelay<D>
Usage Example
let base_transport: Box<dyn Transport> = ...; // Some transport
let delay_distribution = rand::distributions::Uniform::new(0.0, 0.5);
let delayed_transport = TransportWithDelay {
    delay_secs: delay_distribution,
    transport: base_transport,
};

SocketWithDelay<D>

struct SocketWithDelay<D: Distribution<f32> + Send + Sync + 'static> {
    delay_secs: D,
    socket: Arc<RwLock<Box<dyn Socket>>>,
    rng: SmallRng,
}
Implementation of Socket for SocketWithDelay<D>
Important Implementation Detail

TransportWithMessageDrop

struct TransportWithMessageDrop {
    drop_probability: Bernoulli,
    transport: Box<dyn Transport>,
}
Implementation of Transport for TransportWithMessageDrop

SocketWithMessageDrop

struct SocketWithMessageDrop {
    drop_probability: Bernoulli,
    socket: Box<dyn Socket>,
    rng: SmallRng,
}
Implementation of Socket for SocketWithMessageDrop

Trait TransportExt

pub trait TransportExt {
    fn drop_message(self, drop_probability: f64) -> Box<dyn Transport>;
    fn delay<D: DelayMillisDist>(self, delay_proba: D) -> Box<dyn Transport>;
}

Implementation for All Transport

Usage Example
let transport: Box<dyn Transport> = ...;
let unreliable_transport = transport
    .drop_message(0.1)   // 10% drop probability
    .delay(rand::distributions::Uniform::new(0.0, 0.2)); // Delay between 0 and 0.2 seconds

Important Implementation Details


Interactions with Other Parts of the System


Diagram: Flowchart of Main Functions and Their Relationships

flowchart TD
TransportExt -->|drop_message| TransportWithMessageDrop
TransportExt -->|delay| TransportWithDelay
TransportWithMessageDrop --> Transport
TransportWithDelay --> Transport
TransportWithMessageDrop -->|open| SocketWithMessageDrop
TransportWithDelay -->|open| SocketWithDelay
SocketWithMessageDrop --> Socket
SocketWithDelay --> Socket
SocketWithMessageDrop -->|send| DropDecision
DropDecision -->|drop| SendDropped
DropDecision -->|no drop| ForwardSend
SocketWithDelay -->|send| DelaySample
DelaySample -->|spawn task| DelayWait
DelayWait --> ForwardSend
ForwardSend --> InnerSocketSend
InnerSocketSend --> Socket