summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRob Pike <r@golang.org>2010-04-16 16:17:47 -0700
committerRob Pike <r@golang.org>2010-04-16 16:17:47 -0700
commit910aad8711d5bfaf09cf75f4eb5cce2b931d8105 (patch)
treece3cc4113166b9b9b290fc4f72464cd21af83906 /src
parent07729dbfd6e8504c417d0a6f0222af4ecd72b2ab (diff)
downloadgolang-910aad8711d5bfaf09cf75f4eb5cce2b931d8105.tar.gz
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
Diffstat (limited to 'src')
-rw-r--r--src/pkg/rpc/client.go17
1 files changed, 15 insertions, 2 deletions
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.