a cancelled call does not leave its conn for the next one (V-638)
The watchdog and the end of the call race by construction: a cancellation landing as the reply arrives closes a conn the call had already finished with, and c.conn still pointed at the closed socket. It was survivable before this. A write to a closed socket is errWriteLost, which re-dials and retries, and that retry is safe because nothing was sent. So this buys one round trip, not a correctness fix, and the new test says so rather than pretending to catch a break.
This commit is contained in:
+11
-1
@@ -255,8 +255,18 @@ func (c *Client) roundtrip(ctx context.Context, m Method, raw json.RawMessage, r
|
||||
}
|
||||
defer conn.SetDeadline(time.Time{})
|
||||
|
||||
// The watchdog and the end of the call race by construction: a cancellation
|
||||
// landing just as the reply arrives can close a conn this call is already
|
||||
// done with, and c.conn would still point at the closed socket. So a call
|
||||
// whose context ended does not leave the conn behind for the next one,
|
||||
// whichever of the two got there first.
|
||||
done := make(chan struct{})
|
||||
defer close(done)
|
||||
defer func() {
|
||||
close(done)
|
||||
if ctx.Err() != nil {
|
||||
c.drop()
|
||||
}
|
||||
}()
|
||||
go func() {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
|
||||
Reference in New Issue
Block a user