From 910aad8711d5bfaf09cf75f4eb5cce2b931d8105 Mon Sep 17 00:00:00 2001 From: Rob Pike Date: Fri, 16 Apr 2010 16:17:47 -0700 Subject: rpc: Add Close() method to rpc.Client to allow graceful connection teardown. Fixes issue 675. R=rsc, msolo CC=golang-dev http://codereview.appspot.com/882049 --- src/pkg/rpc/client.go | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/pkg/rpc/client.go b/src/pkg/rpc/client.go index cee82ad3c..6b2ddd6f0 100644 --- a/src/pkg/rpc/client.go +++ b/src/pkg/rpc/client.go @@ -37,6 +37,7 @@ type Client struct { enc *gob.Encoder dec *gob.Decoder pending map[uint64]*Call + closing bool } func (client *Client) send(c *Call) { @@ -72,7 +73,7 @@ func (client *Client) input() { response := new(Response) err = client.dec.Decode(response) if err != nil { - if err == os.EOF { + if err == os.EOF && !client.closing { err = io.ErrUnexpectedEOF } break @@ -101,7 +102,9 @@ func (client *Client) input() { _ = call.Done <- call // do not block } client.mutex.Unlock() - log.Stderr("rpc: client protocol error:", err) + if err != os.EOF || !client.closing { + log.Stderr("rpc: client protocol error:", err) + } } // NewClient returns a new Client to handle requests to the @@ -146,6 +149,16 @@ func Dial(network, address string) (*Client, os.Error) { return NewClient(conn), nil } +func (client *Client) Close() os.Error { + if client.shutdown != nil || client.closing { + return os.ErrorString("rpc: already closed") + } + client.mutex.Lock() + client.closing = true + client.mutex.Unlock() + return client.conn.Close() +} + // Go invokes the function asynchronously. It returns the Call structure representing // the invocation. The done channel will signal when the call is complete by returning // the same Call object. If done is nil, Go will allocate a new channel. -- cgit v1.2.3