From 44c365c3e2a3ab0f9f6f9c8ae1fa22e51cd3424f Mon Sep 17 00:00:00 2001
From: Zhou Zhiyao <ZHOU0250@e.ntu.edu.sg>
Date: Mon, 27 Jan 2020 21:03:15 +0800
Subject: [PATCH] rpc: reset writeConn when conn is closed on readErr (#20414)

This change makes the client attempt to reconnect when a write fails.
We already had reconnect support, but the reconnect would previously
happen on the next call after an error. Being more eager leads to a
smoother experience overall.
---
 rpc/client.go | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/rpc/client.go b/rpc/client.go
index a04198ad8..dd06b9469 100644
--- a/rpc/client.go
+++ b/rpc/client.go
@@ -465,7 +465,7 @@ func (c *Client) newMessage(method string, paramsIn ...interface{}) (*jsonrpcMes
 func (c *Client) send(ctx context.Context, op *requestOp, msg interface{}) error {
 	select {
 	case c.reqInit <- op:
-		err := c.write(ctx, msg)
+		err := c.write(ctx, msg, false)
 		c.reqSent <- err
 		return err
 	case <-ctx.Done():
@@ -477,7 +477,7 @@ func (c *Client) send(ctx context.Context, op *requestOp, msg interface{}) error
 	}
 }
 
-func (c *Client) write(ctx context.Context, msg interface{}) error {
+func (c *Client) write(ctx context.Context, msg interface{}, retry bool) error {
 	// The previous write failed. Try to establish a new connection.
 	if c.writeConn == nil {
 		if err := c.reconnect(ctx); err != nil {
@@ -487,6 +487,9 @@ func (c *Client) write(ctx context.Context, msg interface{}) error {
 	err := c.writeConn.writeJSON(ctx, msg)
 	if err != nil {
 		c.writeConn = nil
+		if !retry {
+			return c.write(ctx, msg, true)
+		}
 	}
 	return err
 }
-- 
GitLab