1
0
mirror of https://github.com/golang/go synced 2024-11-25 15:08:02 -07:00

rpc: Add Close() method to rpc.Client to allow graceful connection teardown.

Fixes #675.

R=rsc, msolo
CC=golang-dev
https://golang.org/cl/882049
This commit is contained in:
Rob Pike 2010-04-16 16:17:47 -07:00
parent 0b2e0265ae
commit 3f7da4f861

View File

@ -37,6 +37,7 @@ type Client struct {
enc *gob.Encoder enc *gob.Encoder
dec *gob.Decoder dec *gob.Decoder
pending map[uint64]*Call pending map[uint64]*Call
closing bool
} }
func (client *Client) send(c *Call) { func (client *Client) send(c *Call) {
@ -72,7 +73,7 @@ func (client *Client) input() {
response := new(Response) response := new(Response)
err = client.dec.Decode(response) err = client.dec.Decode(response)
if err != nil { if err != nil {
if err == os.EOF { if err == os.EOF && !client.closing {
err = io.ErrUnexpectedEOF err = io.ErrUnexpectedEOF
} }
break break
@ -101,7 +102,9 @@ func (client *Client) input() {
_ = call.Done <- call // do not block _ = call.Done <- call // do not block
} }
client.mutex.Unlock() 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 // 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 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 // 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 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. // the same Call object. If done is nil, Go will allocate a new channel.