diff --git a/consul/client.go b/consul/client.go index d6d76f3b28..b23077034f 100644 --- a/consul/client.go +++ b/consul/client.go @@ -9,6 +9,7 @@ import ( "strconv" "strings" "sync" + "sync/atomic" "time" "github.com/hashicorp/consul/consul/structs" @@ -61,9 +62,9 @@ type Client struct { // serf cluster in the datacenter eventCh chan serf.Event - // lastServer is the last server we made an RPC call to, + // preferredServer is the last server we made an RPC call to, // this is used to re-use the last connection - lastServer *serverParts + preferredServer *serverParts // Logger uses the provided LogOutput logger *log.Logger @@ -347,8 +348,8 @@ func (c *Client) RPC(method string, args interface{}, reply interface{}) error { // single server now := time.Now() if !c.connRebalanceTime.IsZero() && now.After(c.connRebalanceTime) { - c.logger.Printf("[DEBUG] consul: connection time to server %s exceeded, rotating server connection", c.lastServer.Addr) - c.lastServer = nil + c.logger.Printf("[DEBUG] consul: connection time to server %s exceeded, rotating server connection", c.preferredServer.Addr) + c.preferredServer = nil } // Allocate these vars on the stack before the goto @@ -358,11 +359,9 @@ func (c *Client) RPC(method string, args interface{}, reply interface{}) error { var numLANMembers int var server *serverParts - if c.lastServer != nil { - server = c.lastServer - if server != nil { - goto TRY_RPC - } + if c.preferredServer != nil { + server = c.preferredServer + goto TRY_RPC } // Bail if we can't find any servers @@ -381,13 +380,12 @@ func (c *Client) RPC(method string, args interface{}, reply interface{}) error { TRY_RPC: if err := c.connPool.RPC(c.config.Datacenter, server.Addr, server.Version, method, args, reply); err != nil { c.connRebalanceTime = time.Time{} - c.lastServer = nil - c.lastRPCTime = time.Time{} + c.preferredServer = nil return err } - // Cache the last server - c.lastServer = server + // Cache the last server as our preferred server + _ = atomic.StorePointer(&c.preferredServer, server) return nil }