From dabdad20ad59e84e97331ab48cd5b66ee868036d Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Fri, 30 Sep 2022 19:36:40 +0300 Subject: [PATCH] network: don't wait indefinitely for packet to be sent Peers can be slow, very slow, slow enough to affect node's regular operation. We can't wait for them indefinitely, there has to be a timeout for send operations. This patch uses TimePerBlock as a reference for its timeout. It's relatively big and it doesn't affect tests much, 4+1 scenarios tend to perform a little worse with while 7+2 scenarios work a little better. The difference is in some percents, but all of these tests easily have 10-15% variations from run to run. It's an important step in making our gossip better because we can't have any behavior where neighbors directly block the node forever, refs. #2678 and --- pkg/network/server.go | 2 +- pkg/network/tcp_peer.go | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/pkg/network/server.go b/pkg/network/server.go index cbcc40634..5f8d4f4ea 100644 --- a/pkg/network/server.go +++ b/pkg/network/server.go @@ -1385,7 +1385,7 @@ func (s *Server) iteratePeersWithSendMsg(msg *Message, send func(Peer, bool, []b peer.AddGetAddrSent() } sentN++ - } else if errors.Is(err, errBusy) { + } else if !blocking && errors.Is(err, errBusy) { // Can be retried. continue } else { diff --git a/pkg/network/tcp_peer.go b/pkg/network/tcp_peer.go index e7684f156..6d7dc8bf2 100644 --- a/pkg/network/tcp_peer.go +++ b/pkg/network/tcp_peer.go @@ -87,11 +87,18 @@ func (p *TCPPeer) putPacketIntoQueue(queue chan<- []byte, block bool, msg []byte if !p.Handshaked() { return errStateMismatch } + var ret error if block { + timer := time.NewTimer(p.server.TimePerBlock / 2) select { case queue <- msg: case <-p.done: - return errGone + ret = errGone + case <-timer.C: + ret = errBusy + } + if !errors.Is(ret, errBusy) && !timer.Stop() { + <-timer.C } } else { select { @@ -102,7 +109,7 @@ func (p *TCPPeer) putPacketIntoQueue(queue chan<- []byte, block bool, msg []byte return errBusy } } - return nil + return ret } // EnqueuePacket implements the Peer interface.