Merge pull request #1342 from mlaventure/is-serving-failfast
Disable FailFast on client.IsServing()
This commit is contained in:
commit
edc51c86f2
10
client.go
10
client.go
@ -104,10 +104,14 @@ type Client struct {
|
|||||||
runtime string
|
runtime string
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsServing returns true if the client can successfully connect to the containerd daemon
|
// IsServing returns true if the client can successfully connect to the
|
||||||
// and the healthcheck service returns the SERVING response
|
// containerd daemon and the healthcheck service returns the SERVING
|
||||||
|
// response.
|
||||||
|
// This call will block if a transient error is encountered during
|
||||||
|
// connection. A timeout can be set in the context to ensure it returns
|
||||||
|
// early.
|
||||||
func (c *Client) IsServing(ctx context.Context) (bool, error) {
|
func (c *Client) IsServing(ctx context.Context) (bool, error) {
|
||||||
r, err := c.HealthService().Check(ctx, &grpc_health_v1.HealthCheckRequest{})
|
r, err := c.HealthService().Check(ctx, &grpc_health_v1.HealthCheckRequest{}, grpc.FailFast(false))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"runtime"
|
"runtime"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"google.golang.org/grpc/grpclog"
|
"google.golang.org/grpc/grpclog"
|
||||||
|
|
||||||
@ -73,18 +74,20 @@ func TestMain(m *testing.M) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
client, err := ctrd.waitForStart(ctx)
|
waitCtx, waitCancel := context.WithTimeout(ctx, 2*time.Second)
|
||||||
|
client, err := ctrd.waitForStart(waitCtx)
|
||||||
|
waitCancel()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctrd.Kill()
|
ctrd.Kill()
|
||||||
ctrd.Wait()
|
ctrd.Wait()
|
||||||
fmt.Fprintf(os.Stderr, "%s: %s", err, buf.String())
|
fmt.Fprintf(os.Stderr, "%s: %s\n", err, buf.String())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// print out the version in information
|
// print out the version in information
|
||||||
version, err := client.Version(ctx)
|
version, err := client.Version(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "error getting version: %s", err)
|
fmt.Fprintf(os.Stderr, "error getting version: %s\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +102,7 @@ func TestMain(m *testing.M) {
|
|||||||
if _, err = client.Pull(ctx, testImage, WithPullUnpack); err != nil {
|
if _, err = client.Pull(ctx, testImage, WithPullUnpack); err != nil {
|
||||||
ctrd.Stop()
|
ctrd.Stop()
|
||||||
ctrd.Wait()
|
ctrd.Wait()
|
||||||
fmt.Fprintf(os.Stderr, "%s: %s", err, buf.String())
|
fmt.Fprintf(os.Stderr, "%s: %s\n", err, buf.String())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
package containerd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
winio "github.com/Microsoft/go-winio"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Dialer(address string, timeout time.Duration) (net.Conn, error) {
|
|
||||||
return winio.DialPipe(address, &timeout)
|
|
||||||
}
|
|
||||||
|
|
||||||
func DialAddress(address string) string {
|
|
||||||
return address
|
|
||||||
}
|
|
@ -240,14 +240,9 @@ func TestDaemonRestart(t *testing.T) {
|
|||||||
|
|
||||||
<-statusC
|
<-statusC
|
||||||
|
|
||||||
serving := false
|
waitCtx, waitCancel := context.WithTimeout(ctx, 2*time.Second)
|
||||||
for i := 0; i < 20; i++ {
|
serving, err := client.IsServing(waitCtx)
|
||||||
serving, err = client.IsServing(ctx)
|
waitCancel()
|
||||||
if serving {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
time.Sleep(100 * time.Millisecond)
|
|
||||||
}
|
|
||||||
if !serving {
|
if !serving {
|
||||||
t.Fatalf("containerd did not start within 2s: %v", err)
|
t.Fatalf("containerd did not start within 2s: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ package containerd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"sync"
|
"sync"
|
||||||
@ -44,19 +43,19 @@ func (d *daemon) waitForStart(ctx context.Context) (*Client, error) {
|
|||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
for i := 0; i < 20; i++ {
|
client, err = New(address)
|
||||||
if client == nil {
|
if err != nil {
|
||||||
client, err = New(d.addr)
|
return nil, err
|
||||||
}
|
|
||||||
if err == nil {
|
|
||||||
serving, err = client.IsServing(ctx)
|
|
||||||
if serving {
|
|
||||||
return client, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
time.Sleep(100 * time.Millisecond)
|
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("containerd did not start within 2s: %v", err)
|
serving, err = client.IsServing(ctx)
|
||||||
|
if !serving {
|
||||||
|
client.Close()
|
||||||
|
if err == nil {
|
||||||
|
err = errors.New("connection was successful but service is not available")
|
||||||
|
}
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return client, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *daemon) Stop() error {
|
func (d *daemon) Stop() error {
|
||||||
|
@ -1,31 +1,13 @@
|
|||||||
// +build !windows
|
|
||||||
|
|
||||||
package containerd
|
package containerd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"net"
|
"net"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func isNoent(err error) bool {
|
|
||||||
if err != nil {
|
|
||||||
if nerr, ok := err.(*net.OpError); ok {
|
|
||||||
if serr, ok := nerr.Err.(*os.SyscallError); ok {
|
|
||||||
if serr.Err == syscall.ENOENT {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
type dialResult struct {
|
type dialResult struct {
|
||||||
c net.Conn
|
c net.Conn
|
||||||
err error
|
err error
|
||||||
@ -44,7 +26,7 @@ func Dialer(address string, timeout time.Duration) (net.Conn, error) {
|
|||||||
case <-stopC:
|
case <-stopC:
|
||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
c, err := net.DialTimeout("unix", address, timeout)
|
c, err := dialer(address, timeout)
|
||||||
if isNoent(err) {
|
if isNoent(err) {
|
||||||
<-time.After(10 * time.Millisecond)
|
<-time.After(10 * time.Millisecond)
|
||||||
continue
|
continue
|
||||||
@ -68,7 +50,3 @@ func Dialer(address string, timeout time.Duration) (net.Conn, error) {
|
|||||||
return nil, errors.Errorf("dial %s: no such file or directory", address)
|
return nil, errors.Errorf("dial %s: no such file or directory", address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func DialAddress(address string) string {
|
|
||||||
return fmt.Sprintf("unix://%s", address)
|
|
||||||
}
|
|
32
dialer_unix.go
Normal file
32
dialer_unix.go
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// +build !windows
|
||||||
|
|
||||||
|
package containerd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func isNoent(err error) bool {
|
||||||
|
if err != nil {
|
||||||
|
if nerr, ok := err.(*net.OpError); ok {
|
||||||
|
if serr, ok := nerr.Err.(*os.SyscallError); ok {
|
||||||
|
if serr.Err == syscall.ENOENT {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func dialer(address string, timeout time.Duration) (net.Conn, error) {
|
||||||
|
return net.DialTimeout("unix", address, timeout)
|
||||||
|
}
|
||||||
|
|
||||||
|
func DialAddress(address string) string {
|
||||||
|
return fmt.Sprintf("unix://%s", address)
|
||||||
|
}
|
29
dialer_windows.go
Normal file
29
dialer_windows.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package containerd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
winio "github.com/Microsoft/go-winio"
|
||||||
|
)
|
||||||
|
|
||||||
|
func isNoent(err error) bool {
|
||||||
|
if err != nil {
|
||||||
|
if oerr, ok := err.(*os.PathError); ok {
|
||||||
|
if oerr.Err == syscall.ENOENT {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func dialer(address string, timeout time.Duration) (net.Conn, error) {
|
||||||
|
return winio.DialPipe(address, &timeout)
|
||||||
|
}
|
||||||
|
|
||||||
|
func DialAddress(address string) string {
|
||||||
|
return address
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user