Fix fd-leak in rpcClient close it pro-actively.

This commit is contained in:
Harshavardhana 2016-08-28 20:04:47 -07:00
parent 0513b3ed07
commit cbe87cb2ed
3 changed files with 20 additions and 24 deletions

View File

@ -149,11 +149,14 @@ func (authClient *AuthRPCClient) Call(serviceMethod string, args interface {
args.SetToken(authClient.token)
args.SetTimestamp(authClient.tstamp)
// ..
// Call the underlying rpc.
err = authClient.rpc.Call(serviceMethod, args, reply)
// Invalidate token to mark for re-login on subsequent reconnect.
if err != nil && err == rpc.ErrShutdown {
authClient.isLoggedIn = false
if err != nil {
if err.Error() == rpc.ErrShutdown.Error() {
authClient.isLoggedIn = false
}
}
}
return err

View File

@ -75,7 +75,6 @@ func (rpcClient *RPCClient) dialRPCClient() (*rpc.Client, error) {
// Call makes a RPC call to the remote endpoint using the default codec, namely encoding/gob.
func (rpcClient *RPCClient) Call(serviceMethod string, args interface{}, reply interface{}) error {
// Make a copy below so that we can safely (continue to) work with the rpc.Client.
// Even in the case the two threads would simultaneously find that the connection is not initialised,
// they would both attempt to dial and only one of them would succeed in doing so.
@ -93,15 +92,24 @@ func (rpcClient *RPCClient) Call(serviceMethod string, args interface{}, reply i
// If the RPC fails due to a network-related error, then we reset
// rpc.Client for a subsequent reconnect.
err := rpcLocalStack.Call(serviceMethod, args, reply)
if IsRPCError(err) {
rpcClient.clearRPCClient()
if err != nil {
if err.Error() == rpc.ErrShutdown.Error() {
// Reset rpcClient.rpc to nil to trigger a reconnect in future
// and close the underlying connection.
rpcClient.clearRPCClient()
// Close the underlying connection.
rpcLocalStack.Close()
// Set rpc error as rpc.ErrShutdown type.
err = rpc.ErrShutdown
}
}
return err
}
// Close closes the underlying socket file descriptor.
func (rpcClient *RPCClient) Close() error {
// See comment above for making a copy on local stack
rpcLocalStack := rpcClient.getRPCClient()
@ -115,18 +123,3 @@ func (rpcClient *RPCClient) Close() error {
rpcClient.clearRPCClient()
return rpcLocalStack.Close()
}
// IsRPCError returns true if the error value is due to a network related
// failure, false otherwise.
func IsRPCError(err error) bool {
if err == nil {
return false
}
// The following are net/rpc specific errors that indicate that
// the connection may have been reset. Reset rpcClient.rpc to nil
// to trigger a reconnect in future.
if err == rpc.ErrShutdown {
return true
}
return false
}

View File

@ -48,9 +48,9 @@ var serverCmd = cli.Command{
minio {{.Name}} - {{.Usage}}
USAGE:
minio {{.Name}} [OPTIONS] PATH [PATH...]
minio {{.Name}} [FLAGS] PATH [PATH...]
OPTIONS:
FLAGS:
{{range .Flags}}{{.}}
{{end}}
ENVIRONMENT VARIABLES: