Add granular locking in retryTicker (#6236)

This is to avoid serializing RPC contention on ongoing
parallel operations, the blocking profile indicating
all calls were being serialized through setRetryTicker.
This commit is contained in:
Harshavardhana 2018-08-03 18:57:00 -07:00 committed by GitHub
parent a078703214
commit eabfcea34e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -165,6 +165,15 @@ type RPCClient struct {
} }
func (client *RPCClient) setRetryTicker(ticker *time.Ticker) { func (client *RPCClient) setRetryTicker(ticker *time.Ticker) {
if ticker == nil {
client.RLock()
isNil := client.retryTicker == nil
client.RUnlock()
if isNil {
return
}
}
client.Lock() client.Lock()
defer client.Unlock() defer client.Unlock()
@ -181,18 +190,22 @@ func (client *RPCClient) Call(serviceMethod string, args interface {
}, reply interface{}) (err error) { }, reply interface{}) (err error) {
lockedCall := func() error { lockedCall := func() error {
client.RLock() client.RLock()
defer client.RUnlock() retryTicker := client.retryTicker
client.RUnlock()
if client.retryTicker != nil { if retryTicker != nil {
select { select {
case <-client.retryTicker.C: case <-retryTicker.C:
default: default:
return errRPCRetry return errRPCRetry
} }
} }
client.RLock()
authToken := client.authToken
client.RUnlock()
// Make RPC call. // Make RPC call.
args.SetAuthArgs(AuthArgs{client.authToken, client.args.RPCVersion, time.Now().UTC()}) args.SetAuthArgs(AuthArgs{authToken, client.args.RPCVersion, time.Now().UTC()})
return client.rpcClient.Call(serviceMethod, args, reply) return client.rpcClient.Call(serviceMethod, args, reply)
} }