From 1f4fde9525fcbca902d7eeebab68d84bb71f0595 Mon Sep 17 00:00:00 2001 From: Simon Frei Date: Sun, 15 Sep 2024 21:13:56 +0200 Subject: [PATCH] chore(protocol): prioritize closing a connection (#9711) The read/write loops may keep going for a while on a closing connection with lots of read/write activity, as it's random which select case is chosen. And if the connection is slow or even broken, a single read/write can take a long time/until timeout. Add initial non-blocking selects with only the cases relevant to closing, to prioritize those. --- lib/protocol/protocol.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/protocol/protocol.go b/lib/protocol/protocol.go index b8e399fe1..15191937b 100644 --- a/lib/protocol/protocol.go +++ b/lib/protocol/protocol.go @@ -465,6 +465,11 @@ func (c *rawConnection) dispatcherLoop() (err error) { var msg message state := stateInitial for { + select { + case <-c.closed: + return ErrClosed + default: + } select { case msg = <-c.inbox: case <-c.closed: @@ -758,6 +763,17 @@ func (c *rawConnection) writerLoop() { return } for { + // When the connection is closing or closed, that should happen + // immediately, not compete with the (potentially very busy) outbox. + select { + case hm := <-c.closeBox: + _ = c.writeMessage(hm.msg) + close(hm.done) + return + case <-c.closed: + return + default: + } select { case cc := <-c.clusterConfigBox: err := c.writeMessage(cc)