hawkw/thingbuf

Bursty behavior

FallingSnow opened this issue · 5 comments

I'm running into an issue when using mpsc where all slots in the ring buffer need to be filled before recv_ref() receives a "thing". For example if I create a thingbuf with mpsc::channel::<Vec<u8>>(10), I need to send_ref() 10 times before recv_ref() ever receives anything. And when it does it receives all 10 right after each other. Then it needs to wait for another 10 send_ref() calls to receive another 10.

Is this normal behavior?

hawkw commented

Hmm, that doesn't sound right. What version are you using?

thingbuf = "0.1.4"

I didn't think so. I must be doing something wrong. I'll look into it some more and come back if I'm still stuck.

I tried to replicate my issue in a minimal repo but couldn't so I started disabling pieces of my program.

Oddly I've discovered when switching

let udp_socket = Socket::new(socket2::Domain::IPV4, Type::DGRAM, Some(Protocol::UDP)).unwrap();
udp_socket.set_reuse_port(true).unwrap();
udp_socket.set_recv_buffer_size(MAX_MTU * 100).unwrap();
udp_socket
        .bind(&socket2::SockAddr::from(socket_addr))
        .unwrap();
let udp_socket = UdpSocket::from_std(udp_socket.into()).unwrap();

to

let udp_socket = UdpSocket::bind(socket_addr).await.unwrap();

the issue goes away.

My guess is when using socket2's implementation it doesn't clear the read interest flag in tokio. Maybe?? :/ But then again that shouldn't prevent thingbuf from sending the message. I have no idea.

Okay, that was definitely the issue. I don't understand how but it was. I've replaced the socket2 code with the following and everything is working as expected now.

let res = unsafe { libc::setsockopt(udp_socket.as_raw_fd(), libc::SOL_SOCKET, libc::SO_RCVBUF, &(MAX_MTU * 100) as *const _ as *const libc::c_void, std::mem::size_of::<u32>() as u32) };

Thank you!

hawkw commented

Huh, interesting! Glad you've figured it out!