Skip to content

Commit

Permalink
tetra: uses grpc.NewClient in NewClientWithDefaultContext
Browse files Browse the repository at this point in the history
Switch from grpc.DialContext to grpc.NewClient which does not perform
any I/O and wait lazily for the first RPC call to be made to connect.
This is the way to go as DialContext is getting deprecated and the gRPC
team has been writing that using the other is an anti-pattern.

https://github.com/grpc/grpc-go/blob/master/Documentation/anti-patterns.md

Signed-off-by: Mahe Tardy <[email protected]>
  • Loading branch information
mtardy committed Jul 29, 2024
1 parent f37b9e5 commit 663a1e2
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 36 deletions.
49 changes: 21 additions & 28 deletions cmd/tetra/common/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package common

import (
"context"
"fmt"
"os/signal"
"syscall"
"time"
Expand Down Expand Up @@ -61,47 +62,39 @@ func CliRun(fn func(ctx context.Context, cli tetragon.FineGuidanceSensorsClient)
CliRunErr(fn, func(_ error) {})
}

type ConnectedClient struct {
type ClientWithContext struct {
Client tetragon.FineGuidanceSensorsClient
Ctx context.Context
conn *grpc.ClientConn
cancel context.CancelFunc
}

// Close cleanup resources, it closes the connection and cancel the context
func (c ConnectedClient) Close() {
func (c ClientWithContext) Close() {
c.conn.Close()
c.cancel()
}

// NewConnectedClient return a connected client to a tetragon server, caller
// must call Close() on the client. On failure to connect, this function calls
// Fatal() thus stopping execution.
func NewConnectedClient() ConnectedClient {
c := ConnectedClient{}
c.Ctx, c.cancel = signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
// NewClientWithDefaultContext return a client to a tetragon server accompanied
// with an initialized context that can be used for the RPC call, caller must
// call Close() on the client.
func NewClientWithDefaultContext() (*ClientWithContext, error) {
c := &ClientWithContext{}

var serverAddr string
var err error
var timeout context.Context
timeout, c.cancel = context.WithTimeout(context.Background(), Timeout)
// we don't need the cancelFunc here as calling cancel on timeout, the
// parent, will cancel its children.
c.Ctx, _ = signal.NotifyContext(timeout, syscall.SIGINT, syscall.SIGTERM)

backoff := time.Second
attempts := 0
for {
c.conn, serverAddr, err = connect(c.Ctx)
if err != nil {
if attempts < Retries {
// Exponential backoff
attempts++
logger.GetLogger().WithField("server-address", serverAddr).WithField("attempts", attempts).WithError(err).Error("Connection attempt failed, retrying...")
time.Sleep(backoff)
backoff *= 2
continue
}
logger.GetLogger().WithField("server-address", serverAddr).WithField("attempts", attempts).WithError(err).Fatal("Failed to connect to server")
}
break
}
address := ResolveServerAddress()

var err error
c.conn, err = grpc.NewClient(address, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
return nil, fmt.Errorf("failed to create gRPC client with address %s: %w", address, err)
}
c.Client = tetragon.NewFineGuidanceSensorsClient(c.conn)
return c

return c, nil
}
31 changes: 23 additions & 8 deletions cmd/tetra/tracingpolicy/tracingpolicy.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ func New() *cobra.Command {
Short: "add a new sensor based on a tracing policy",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
c := common.NewConnectedClient()
c, err := common.NewClientWithDefaultContext()
if err != nil {
return fmt.Errorf("failed create gRPC client: %w", err)
}
defer c.Close()

yamlb, err := os.ReadFile(args[0])
Expand All @@ -53,10 +56,13 @@ func New() *cobra.Command {
Short: "delete a tracing policy",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
c := common.NewConnectedClient()
c, err := common.NewClientWithDefaultContext()
if err != nil {
return fmt.Errorf("failed create gRPC client: %w", err)
}
defer c.Close()

_, err := c.Client.DeleteTracingPolicy(c.Ctx, &tetragon.DeleteTracingPolicyRequest{
_, err = c.Client.DeleteTracingPolicy(c.Ctx, &tetragon.DeleteTracingPolicyRequest{
Name: args[0],
Namespace: tpDelNamespaceFlag,
})
Expand All @@ -76,10 +82,13 @@ func New() *cobra.Command {
Long: "Enable a disabled tracing policy. Use disable to re-disable the tracing policy.",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
c := common.NewConnectedClient()
c, err := common.NewClientWithDefaultContext()
if err != nil {
return fmt.Errorf("failed create gRPC client: %w", err)
}
defer c.Close()

_, err := c.Client.EnableTracingPolicy(c.Ctx, &tetragon.EnableTracingPolicyRequest{
_, err = c.Client.EnableTracingPolicy(c.Ctx, &tetragon.EnableTracingPolicyRequest{
Name: args[0],
Namespace: tpEnableNamespaceFlag,
})
Expand All @@ -99,10 +108,13 @@ func New() *cobra.Command {
Long: "Disable an enabled tracing policy. Use enable to re-enable the tracing policy.",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
c := common.NewConnectedClient()
c, err := common.NewClientWithDefaultContext()
if err != nil {
return fmt.Errorf("failed create gRPC client: %w", err)
}
defer c.Close()

_, err := c.Client.DisableTracingPolicy(c.Ctx, &tetragon.DisableTracingPolicyRequest{
_, err = c.Client.DisableTracingPolicy(c.Ctx, &tetragon.DisableTracingPolicyRequest{
Name: args[0],
Namespace: tpDisableNamespaceFlag,
})
Expand Down Expand Up @@ -130,7 +142,10 @@ func New() *cobra.Command {
return nil
},
RunE: func(cmd *cobra.Command, _ []string) error {
c := common.NewConnectedClient()
c, err := common.NewClientWithDefaultContext()
if err != nil {
return fmt.Errorf("failed create gRPC client: %w", err)
}
defer c.Close()

res, err := c.Client.ListTracingPolicies(c.Ctx, &tetragon.ListTracingPoliciesRequest{})
Expand Down

0 comments on commit 663a1e2

Please sign in to comment.