pkg/rpc: return context error if ready after DialContext fails

the net package does not make it easy to know if DialContext
failed because the context was done. it's important for some
of our tests that canceled contexts are detected as such, so
we accept the small race that's arguably correct (the context
must be canceled asynchronously) to ensure we always return
the context error if available.

Change-Id: I058064d5c666e5353b74fb5bd300bf7abe537ff5
This commit is contained in:
Jeff Wendling 2019-10-04 10:59:49 -06:00
parent 6afa4dd9cf
commit 64e43e555e
2 changed files with 13 additions and 3 deletions

View File

@ -68,8 +68,18 @@ func (d Dialer) dialContext(ctx context.Context, address string) (net.Conn, erro
conn, err := new(net.Dialer).DialContext(ctx, "tcp", address)
if err != nil {
// N.B. this error is not wrapped on purpose! grpc code cares about inspecting
// it and it's not smart enough to attempt to do any unwrapping. :(
return nil, err
// it and it's not smart enough to attempt to do any unwrapping. :( Additionally
// DialContext does not return an error that can be inspected easily to see if it
// came from the context being canceled. Thus, we do this racy thing where if the
// context is canceled at this point, we return it, rather than return the error
// from dialing. It's a slight lie, but arguably still correct because the cancel
// must be racing with the dial anyway.
select {
case <-ctx.Done():
return nil, ctx.Err()
default:
return nil, err
}
}
return &timedConn{

View File

@ -17,7 +17,7 @@ import (
)
// Error is the default error class
var Error = errs.Class("trust:")
var Error = errs.Class("trust")
var mon = monkit.Package()