Merge pull request #8120 from dcantah/grpc-shim-callbackfn
runtime/v2: Call onCloseWithShimLog for grpc shims
This commit is contained in:
commit
921f49b5f0
@ -29,8 +29,8 @@ import (
|
|||||||
|
|
||||||
"github.com/containerd/ttrpc"
|
"github.com/containerd/ttrpc"
|
||||||
"github.com/hashicorp/go-multierror"
|
"github.com/hashicorp/go-multierror"
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
|
"google.golang.org/grpc/connectivity"
|
||||||
"google.golang.org/grpc/credentials/insecure"
|
"google.golang.org/grpc/credentials/insecure"
|
||||||
|
|
||||||
eventstypes "github.com/containerd/containerd/api/events"
|
eventstypes "github.com/containerd/containerd/api/events"
|
||||||
@ -221,7 +221,7 @@ func makeConnection(ctx context.Context, address string, onClose func()) (_ io.C
|
|||||||
params.Protocol = "ttrpc"
|
params.Protocol = "ttrpc"
|
||||||
}
|
}
|
||||||
|
|
||||||
log.G(ctx).WithFields(logrus.Fields{
|
log.G(ctx).WithFields(log.Fields{
|
||||||
"address": params.Address,
|
"address": params.Address,
|
||||||
"protocol": params.Protocol,
|
"protocol": params.Protocol,
|
||||||
}).Debug("shim bootstrap parameters")
|
}).Debug("shim bootstrap parameters")
|
||||||
@ -238,38 +238,78 @@ func makeConnection(ctx context.Context, address string, onClose func()) (_ io.C
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
ttrpcClient := ttrpc.NewClient(conn, ttrpc.WithOnClose(onClose))
|
return ttrpc.NewClient(conn, ttrpc.WithOnClose(onClose)), nil
|
||||||
defer func() {
|
|
||||||
if retErr != nil {
|
|
||||||
ttrpcClient.Close()
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
return ttrpcClient, nil
|
|
||||||
case "grpc":
|
case "grpc":
|
||||||
|
ctx, cancel := context.WithTimeout(ctx, time.Second*100)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
gopts := []grpc.DialOption{
|
gopts := []grpc.DialOption{
|
||||||
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
||||||
|
grpc.WithBlock(),
|
||||||
}
|
}
|
||||||
|
return grpcDialContext(ctx, dialer.DialAddress(params.Address), onClose, gopts...)
|
||||||
conn, err := grpc.DialContext(ctx, dialer.DialAddress(params.Address), gopts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to create GRPC connection: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
if retErr != nil {
|
|
||||||
conn.Close()
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
// TODO: figure out how to invoke onCloseWithShimLog callback when shim connection is closed.
|
|
||||||
|
|
||||||
return conn, nil
|
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unexpected protocol: %q", params.Protocol)
|
return nil, fmt.Errorf("unexpected protocol: %q", params.Protocol)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// grpcDialContext and the underlying grpcConn type exist solely
|
||||||
|
// so we can have something similar to ttrpc.WithOnClose to have
|
||||||
|
// a callback run when the connection is severed or explicitly closed.
|
||||||
|
func grpcDialContext(
|
||||||
|
ctx context.Context,
|
||||||
|
target string,
|
||||||
|
onClose func(),
|
||||||
|
gopts ...grpc.DialOption,
|
||||||
|
) (*grpcConn, error) {
|
||||||
|
client, err := grpc.DialContext(ctx, target, gopts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to create GRPC connection: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
done := make(chan struct{})
|
||||||
|
go func() {
|
||||||
|
gctx := context.Background()
|
||||||
|
sourceState := connectivity.Ready
|
||||||
|
for {
|
||||||
|
if client.WaitForStateChange(gctx, sourceState) {
|
||||||
|
state := client.GetState()
|
||||||
|
if state == connectivity.Idle || state == connectivity.Shutdown {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
// Could be transient failure. Lets see if we can get back to a working
|
||||||
|
// state.
|
||||||
|
log.G(gctx).WithFields(log.Fields{
|
||||||
|
"state": state,
|
||||||
|
"addr": target,
|
||||||
|
}).Warn("shim grpc connection unexpected state")
|
||||||
|
sourceState = state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onClose()
|
||||||
|
close(done)
|
||||||
|
}()
|
||||||
|
|
||||||
|
return &grpcConn{
|
||||||
|
ClientConn: client,
|
||||||
|
onCloseDone: done,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type grpcConn struct {
|
||||||
|
*grpc.ClientConn
|
||||||
|
onCloseDone chan struct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gc *grpcConn) UserOnCloseWait(ctx context.Context) error {
|
||||||
|
select {
|
||||||
|
case <-gc.onCloseDone:
|
||||||
|
return nil
|
||||||
|
case <-ctx.Done():
|
||||||
|
return ctx.Err()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type shim struct {
|
type shim struct {
|
||||||
bundle *Bundle
|
bundle *Bundle
|
||||||
client any
|
client any
|
||||||
@ -300,6 +340,10 @@ func (s *shim) Close() error {
|
|||||||
return ttrpcClient.Close()
|
return ttrpcClient.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if grpcClient, ok := s.client.(*grpcConn); ok {
|
||||||
|
return grpcClient.Close()
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,6 +362,16 @@ func (s *shim) Delete(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if grpcClient, ok := s.client.(*grpcConn); ok {
|
||||||
|
if err := grpcClient.Close(); err != nil {
|
||||||
|
result = multierror.Append(result, fmt.Errorf("failed to close grpc client: %w", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := grpcClient.UserOnCloseWait(ctx); err != nil {
|
||||||
|
result = multierror.Append(result, fmt.Errorf("close wait error: %w", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if err := s.bundle.Delete(); err != nil {
|
if err := s.bundle.Delete(); err != nil {
|
||||||
log.G(ctx).WithField("id", s.ID()).WithError(err).Error("failed to delete bundle")
|
log.G(ctx).WithField("id", s.ID()).WithError(err).Error("failed to delete bundle")
|
||||||
result = multierror.Append(result, fmt.Errorf("failed to delete bundle: %w", err))
|
result = multierror.Append(result, fmt.Errorf("failed to delete bundle: %w", err))
|
||||||
|
Loading…
Reference in New Issue
Block a user