mirror of
https://github.com/golang/go
synced 2024-11-20 08:54:40 -07:00
rpc: don't panic on write error.
The mechanism to record the error in the call is already in place. Fixes #2382. R=golang-dev, dsymonds, bradfitz, r CC=golang-dev https://golang.org/cl/5307043
This commit is contained in:
parent
fc3ce34903
commit
4c56c30b78
@ -85,7 +85,8 @@ func (client *Client) send(c *Call) {
|
||||
client.request.Seq = c.seq
|
||||
client.request.ServiceMethod = c.ServiceMethod
|
||||
if err := client.codec.WriteRequest(&client.request, c.Args); err != nil {
|
||||
panic("rpc: client encode error: " + err.String())
|
||||
c.Error = err
|
||||
c.done()
|
||||
}
|
||||
}
|
||||
|
||||
@ -251,10 +252,10 @@ func (client *Client) Close() os.Error {
|
||||
// the same Call object. If done is nil, Go will allocate a new channel.
|
||||
// If non-nil, done must be buffered or Go will deliberately crash.
|
||||
func (client *Client) Go(serviceMethod string, args interface{}, reply interface{}, done chan *Call) *Call {
|
||||
c := new(Call)
|
||||
c.ServiceMethod = serviceMethod
|
||||
c.Args = args
|
||||
c.Reply = reply
|
||||
call := new(Call)
|
||||
call.ServiceMethod = serviceMethod
|
||||
call.Args = args
|
||||
call.Reply = reply
|
||||
if done == nil {
|
||||
done = make(chan *Call, 10) // buffered.
|
||||
} else {
|
||||
@ -266,14 +267,14 @@ func (client *Client) Go(serviceMethod string, args interface{}, reply interface
|
||||
log.Panic("rpc: done channel is unbuffered")
|
||||
}
|
||||
}
|
||||
c.Done = done
|
||||
call.Done = done
|
||||
if client.shutdown {
|
||||
c.Error = ErrShutdown
|
||||
c.done()
|
||||
return c
|
||||
call.Error = ErrShutdown
|
||||
call.done()
|
||||
return call
|
||||
}
|
||||
client.send(c)
|
||||
return c
|
||||
client.send(call)
|
||||
return call
|
||||
}
|
||||
|
||||
// Call invokes the named function, waits for it to complete, and returns its error status.
|
||||
|
@ -467,6 +467,32 @@ func TestCountMallocsOverHTTP(t *testing.T) {
|
||||
fmt.Printf("mallocs per HTTP rpc round trip: %d\n", countMallocs(dialHTTP, t))
|
||||
}
|
||||
|
||||
type writeCrasher struct{}
|
||||
|
||||
func (writeCrasher) Close() os.Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (writeCrasher) Read(p []byte) (int, os.Error) {
|
||||
return 0, os.EOF
|
||||
}
|
||||
|
||||
func (writeCrasher) Write(p []byte) (int, os.Error) {
|
||||
return 0, os.NewError("fake write failure")
|
||||
}
|
||||
|
||||
func TestClientWriteError(t *testing.T) {
|
||||
c := NewClient(writeCrasher{})
|
||||
res := false
|
||||
err := c.Call("foo", 1, &res)
|
||||
if err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
if err.String() != "fake write failure" {
|
||||
t.Error("unexpected value of error:", err)
|
||||
}
|
||||
}
|
||||
|
||||
func benchmarkEndToEnd(dial func() (*Client, os.Error), b *testing.B) {
|
||||
b.StopTimer()
|
||||
once.Do(startServer)
|
||||
|
Loading…
Reference in New Issue
Block a user