Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drain udp socket recv buffer without any significant delay #87

Closed
goshawk-3 opened this issue Jan 4, 2022 · 0 comments · Fixed by #89
Closed

Drain udp socket recv buffer without any significant delay #87

goshawk-3 opened this issue Jan 4, 2022 · 0 comments · Fixed by #89
Assignees
Labels
mark:testnet status:minor Low priority improvements type:enhancement Issues concerning code or feature improvement (performance, refactoring, etc)

Comments

@goshawk-3
Copy link
Contributor

Describe what you want implemented
As it turns out that under heavy load a kadcast peer may lose chunks (respectively messages) due to full udp_recv_buffer we should consider to drain recv socket as fast as possible.

Currently, we receive a chunk from socket, try to decode full msg (a CPU-intensive task) and then receive next chunk

  let (_, remote_address) =
                socket.recv_from(&mut bytes).await.map_err(|e| {
                    error!("Error receiving from socket {}", e);
                    e
                })?;

            match Message::unmarshal_binary(&mut &bytes[..]) {
                Ok(deser) => {
                    trace!("> Received {:?}", deser);
                    let to_process = decoder.decode(deser);

Instead we could try to process/decode the received chunk asynchronously.

Pseudo idea:

loop {
 # recv_from a socket
 socket.recv_from(&mut chunk).await.map_err(|e| {
                    error!("Error receiving from socket {}", e);
                    e
                })?;

 # run fast sanity check, drop and report if invalid

 # delegate it to another task
 channel.send(chunk)
 
}

Describe "Why" this is needed
This should mitigate the pressure on OS-level udp_recv_buffer and give us more control over chunk buffering. That's said, we'll be able to trace/report when a chunk is lost, resize buffer/chan size dynamically if needed.

Describe alternatives you've considered
In addition to this idea, a kadcast peer will be able to set udp_recv_buffer at socket level (SO_RCVBUF). However this might be limited due to OS-level net.core.rmem_max config.

Additional context
Currently, a system-test with following params CLUSTER_SIZE=10 MSG_SIZE=1000000 WAIT=5s go test -count=10 -tags=testbed -run TestCluster on Linux will pass only if net.core.rmem_default is set to a large number.

@goshawk-3 goshawk-3 added status:minor Low priority improvements type:enhancement Issues concerning code or feature improvement (performance, refactoring, etc) mark:testnet labels Jan 4, 2022
@goshawk-3 goshawk-3 changed the title Drain udp socket recv buffer without any significant delays Drain udp socket recv buffer without any significant delay Jan 4, 2022
@goshawk-3 goshawk-3 self-assigned this Jan 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
mark:testnet status:minor Low priority improvements type:enhancement Issues concerning code or feature improvement (performance, refactoring, etc)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant