Update pkg/ttrpcutil with improved pipe dial logic
Signed-off-by: Kevin Parsons <kevpar@microsoft.com>
This commit is contained in:
parent
daf12cd194
commit
b16e7c5de1
@ -19,6 +19,7 @@
|
|||||||
package ttrpcutil
|
package ttrpcutil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
@ -28,33 +29,31 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func ttrpcDial(address string, timeout time.Duration) (net.Conn, error) {
|
func ttrpcDial(address string, timeout time.Duration) (net.Conn, error) {
|
||||||
var c net.Conn
|
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||||
var lastError error
|
defer cancel()
|
||||||
timedOutError := errors.Errorf("timed out waiting for npipe %s", address)
|
|
||||||
start := time.Now()
|
// If there is nobody serving the pipe we limit the timeout for this case to
|
||||||
|
// 5 seconds because any shim that would serve this endpoint should serve it
|
||||||
|
// within 5 seconds.
|
||||||
|
serveTimer := time.NewTimer(5 * time.Second)
|
||||||
|
defer serveTimer.Stop()
|
||||||
for {
|
for {
|
||||||
remaining := timeout - time.Since(start)
|
c, err := winio.DialPipeContext(ctx, address)
|
||||||
if remaining <= 0 {
|
if err != nil {
|
||||||
lastError = timedOutError
|
if os.IsNotExist(err) {
|
||||||
break
|
select {
|
||||||
}
|
case <-serveTimer.C:
|
||||||
c, lastError = winio.DialPipe(address, &remaining)
|
return nil, errors.Wrap(os.ErrNotExist, "pipe not found before timeout")
|
||||||
if lastError == nil {
|
default:
|
||||||
break
|
// Wait 10ms for the shim to serve and try again.
|
||||||
}
|
|
||||||
if !os.IsNotExist(lastError) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
// There is nobody serving the pipe. We limit the timeout for this case
|
|
||||||
// to 5 seconds because any shim that would serve this endpoint should
|
|
||||||
// serve it within 5 seconds. We use the passed in timeout for the
|
|
||||||
// `DialPipe` timeout if the pipe exists however to give the pipe time
|
|
||||||
// to `Accept` the connection.
|
|
||||||
if time.Since(start) >= 5*time.Second {
|
|
||||||
lastError = timedOutError
|
|
||||||
break
|
|
||||||
}
|
|
||||||
time.Sleep(10 * time.Millisecond)
|
time.Sleep(10 * time.Millisecond)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
} else if err == context.DeadlineExceeded {
|
||||||
|
return nil, errors.Wrapf(err, "timed out waiting for npipe %s", address)
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return c, nil
|
||||||
}
|
}
|
||||||
return c, lastError
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user