turmoil
turmoil copied to clipboard
Enable testing of backpressure from TCP connections
There are certain error conditions we want to test out that only happen when the TCP connection stalls and doesn't write right away (returns Poll::Pending
on write). Would be great if Turmoil allowed for that - so in the simple code below, the host b
just waited forever instead of the simulation panicking with socket buffer full
.
use std::{
net::{IpAddr, Ipv4Addr},
time::Duration,
};
use tokio::{io::AsyncWriteExt, time::sleep};
use turmoil::{
net::{TcpListener, TcpStream},
Result,
};
#[test]
fn want_backpressure() -> Result {
let mut sim = turmoil::Builder::new().build();
sim.host("b", || async {
let listener = TcpListener::bind((IpAddr::from(Ipv4Addr::UNSPECIFIED), 9876))
.await
.expect("Bind to local host");
let (mut conn, _addr) = listener.accept().await.expect("Accept conn");
for _ in 0..10000 {
conn.write_all(b"message").await.expect("Write");
conn.flush().await.expect("flush");
}
Ok(())
});
sim.client("a", async move {
let _conn = TcpStream::connect("b:9876").await.expect("Open to b");
sleep(Duration::from_millis(100)).await;
Ok(())
});
sim.run()
}
I also just ran into this. I think this is related to turmoil skipping flow-control logic?
https://github.com/tokio-rs/turmoil/blob/6728fbeea09b1486c16b0d635c400ae2b276a6a8/src/envelope.rs#L26-L28
Is there any appetite to add flow-control emulation to turmoil?
In my use case I am trying to use turmoil for a test case that sends a large amount (~100 Gb) of data, but was running into this panic when trying to reproduce a different issue that I was running into 😄 .
I think there is an appetite for back pressure, but I'm not sure we need to implement a flow control message protocol. One idea for this is that we just poll on write when the egress tcp buffer fills (doesn't exist today) instead of putting packets directly on the network.