Skip to content

Commit

Permalink
Rework client, connect, to simplify and prepare for simpler healing.
Browse files Browse the repository at this point in the history
Previously we had a single 'client' per grpc.ClientConnInterface.
This created a lot of complexity, particularly in connect.

This rework of client moves to a single 'client' that can handle
multiple grpc.ClientConnInterfaces.

This vastly simplified both the client chain and connect chain.

Finally, heal has been temporarily removed in preparation for a rework
of heal focused on back propogating Connection 'DOWN' events via
monitor.  The net net at the end of the process should be:

1)  Refresh is only originated by actual clients, not the 'client' part
of passthrough NSEs
2)  Heal will only be originated by actual clients, not the 'client' part
pf passthrough NSEs.

Signed-off-by: Ed Warnicke <[email protected]>
  • Loading branch information
edwarnicke committed Sep 20, 2021
1 parent 07ced33 commit c7c2da4
Show file tree
Hide file tree
Showing 38 changed files with 670 additions and 3,480 deletions.
51 changes: 0 additions & 51 deletions pkg/networkservice/chains/client/README.md

This file was deleted.

145 changes: 26 additions & 119 deletions pkg/networkservice/chains/client/client.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
// Copyright (c) 2020-2021 Cisco Systems, Inc.
//
// Copyright (c) 2021 Doc.ai and/or its affiliates.
// Copyright (c) 2021 Cisco and/or its affiliates.
//
// SPDX-License-Identifier: Apache-2.0
//
Expand All @@ -21,144 +19,53 @@ package client

import (
"context"
"net/url"
"time"

"github.com/google/uuid"
"google.golang.org/grpc"

"github.com/networkservicemesh/sdk/pkg/networkservice/common/begin"

"github.com/networkservicemesh/api/pkg/api/networkservice"

"github.com/networkservicemesh/sdk/pkg/networkservice/common/begin"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/clientconn"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/clienturl"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/connect"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/heal"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/dial"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/null"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/refresh"
"github.com/networkservicemesh/sdk/pkg/networkservice/common/updatepath"
"github.com/networkservicemesh/sdk/pkg/networkservice/core/adapters"
"github.com/networkservicemesh/sdk/pkg/networkservice/core/chain"
"github.com/networkservicemesh/sdk/pkg/networkservice/utils/metadata"
)

type clientOptions struct {
name string
additionalFunctionality []networkservice.NetworkServiceClient
authorizeClient networkservice.NetworkServiceClient
dialOptions []grpc.DialOption
dialTimeout time.Duration
}

// Option modifies default client chain values.
type Option func(c *clientOptions)

// WithName sets name for the client.
func WithName(name string) Option {
return Option(func(c *clientOptions) {
c.name = name
})
}

// WithAdditionalFunctionality sets additionalFunctionality for the client. Note: this adds into tail of the client chain.
func WithAdditionalFunctionality(additionalFunctionality ...networkservice.NetworkServiceClient) Option {
return Option(func(c *clientOptions) {
c.additionalFunctionality = additionalFunctionality
})
}

// WithAuthorizeClient sets authorizeClient for the client chain.
func WithAuthorizeClient(authorizeClient networkservice.NetworkServiceClient) Option {
if authorizeClient == nil {
panic("authorizeClient cannot be nil")
}
return Option(func(c *clientOptions) {
c.authorizeClient = authorizeClient
})
}

// WithDialOptions sets dial options
func WithDialOptions(dialOptions ...grpc.DialOption) Option {
return Option(func(c *clientOptions) {
c.dialOptions = dialOptions
})
}

// WithDialTimeout sets dial timeout
func WithDialTimeout(dialTimeout time.Duration) Option {
return func(c *clientOptions) {
c.dialTimeout = dialTimeout
}
}

// NewClient - returns a (1.) case NSM client.
// NewClient - returns case NSM client.
// - ctx - context for the lifecycle of the *Client* itself. Cancel when discarding the client.
// - cc - grpc.ClientConnInterface for the endpoint to which this client should connect
func NewClient(ctx context.Context, connectTo *url.URL, clientOpts ...Option) networkservice.NetworkServiceClient {
rv := new(networkservice.NetworkServiceClient)
func NewClient(ctx context.Context, clientOpts ...Option) networkservice.NetworkServiceClient {
var opts = &clientOptions{
name: "client-" + uuid.New().String(),
authorizeClient: null.NewClient(),
dialTimeout: 100 * time.Millisecond,
refreshClient: refresh.NewClient(ctx),
}
for _, opt := range clientOpts {
opt(opts)
}

*rv = chain.NewNetworkServiceClient(
updatepath.NewClient(opts.name),
begin.NewClient(),
metadata.NewClient(),
refresh.NewClient(ctx),
adapters.NewServerToClient(
chain.NewNetworkServiceServer(
heal.NewServer(ctx,
heal.WithOnHeal(rv),
heal.WithOnRestore(heal.OnRestoreRestore),
heal.WithRestoreTimeout(time.Minute)),
clienturl.NewServer(connectTo),
connect.NewServer(ctx, func(ctx context.Context, cc grpc.ClientConnInterface) networkservice.NetworkServiceClient {
return chain.NewNetworkServiceClient(
append(
opts.additionalFunctionality,
opts.authorizeClient,
heal.NewClient(ctx, networkservice.NewMonitorConnectionClient(cc)),
networkservice.NewNetworkServiceClient(cc),
)...,
)
},
connect.WithDialOptions(opts.dialOptions...),
connect.WithDialTimeout(opts.dialTimeout)),
),
),
)
return *rv
}

// NewClientFactory - returns a (3.) case func(cc grpc.ClientConnInterface) NSM client factory.
func NewClientFactory(clientOpts ...Option) connect.ClientFactory {
return func(ctx context.Context, cc grpc.ClientConnInterface) networkservice.NetworkServiceClient {
var rv networkservice.NetworkServiceClient
var opts = &clientOptions{
name: "client-" + uuid.New().String(),
authorizeClient: null.NewClient(),
}
for _, opt := range clientOpts {
opt(opts)
}
rv = chain.NewNetworkServiceClient(
return chain.NewNetworkServiceClient(
append(
[]networkservice.NetworkServiceClient{
updatepath.NewClient(opts.name),
begin.NewClient(),
metadata.NewClient(),
opts.refreshClient,
clienturl.NewClient(opts.clientURL),
clientconn.NewClient(opts.cc),
},
append(
append([]networkservice.NetworkServiceClient{
updatepath.NewClient(opts.name),
begin.NewClient(),
metadata.NewClient(),
refresh.NewClient(ctx),
// TODO: move back to the end of the chain when `begin` chain element will be ready
heal.NewClient(ctx, networkservice.NewMonitorConnectionClient(cc)),
}, opts.additionalFunctionality...),
opts.additionalFunctionality,
dial.NewClient(ctx,
dial.WithDialOptions(opts.dialOptions...),
dial.WithDialTimeOut(opts.dialTimeout),
),
opts.authorizeClient,
networkservice.NewNetworkServiceClient(cc),
)...)
return rv
}
connect.NewClient(),
)...,
)...,
)
}
Loading

0 comments on commit c7c2da4

Please sign in to comment.