Răsfoiți Sursa

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.
Simon Frei 1 an în urmă
părinte
comite
1f4fde9525
1 a modificat fișierele cu 16 adăugiri și 0 ștergeri
  1. 16 0
      lib/protocol/protocol.go

+ 16 - 0
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)