Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cmd): adding timeout flag #3580

Merged
merged 12 commits into from
Oct 3, 2024
41 changes: 36 additions & 5 deletions api/rpc/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"
"net/http"
"time"

"github.com/filecoin-project/go-jsonrpc"

Expand Down Expand Up @@ -41,6 +42,18 @@ type Client struct {
closer multiClientCloser
}

type RPCClientOption func(*clientConfig)

type clientConfig struct {
timeout time.Duration
}

func WithTimeout(timeout time.Duration) RPCClientOption {
return func(c *clientConfig) {
c.timeout = timeout
}
}

// multiClientCloser is a wrapper struct to close clients across multiple namespaces.
type multiClientCloser struct {
closers []jsonrpc.ClientCloser
Expand All @@ -65,22 +78,40 @@ func (c *Client) Close() {

// NewClient creates a new Client with one connection per namespace with the
// given token as the authorization token.
func NewClient(ctx context.Context, addr, token string) (*Client, error) {
func NewClient(ctx context.Context, addr, token string, opts ...RPCClientOption) (*Client, error) {
config := &clientConfig{}
for _, opt := range opts {
opt(config)
}

authHeader := http.Header{perms.AuthKey: []string{fmt.Sprintf("Bearer %s", token)}}
return newClient(ctx, addr, authHeader)
return newClient(ctx, addr, authHeader, config)
}

func newClient(ctx context.Context, addr string, authHeader http.Header) (*Client, error) {
var multiCloser multiClientCloser
func newClient(ctx context.Context, addr string, authHeader http.Header, config *clientConfig) (*Client, error) {
var client Client
var multiCloser multiClientCloser

httpClient := &http.Client{
Timeout: config.timeout,
}

for name, module := range moduleMap(&client) {
closer, err := jsonrpc.NewClient(ctx, addr, name, module, authHeader)
closer, err := jsonrpc.NewMergeClient(
ctx,
addr,
name,
[]interface{}{module},
authHeader,
jsonrpc.WithHTTPClient(httpClient),
)
if err != nil {
return nil, err
}
multiCloser.register(closer)
}

client.closer = multiCloser
return &client, nil
}

Expand Down
16 changes: 15 additions & 1 deletion cmd/rpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"path/filepath"
"time"

"github.com/spf13/cobra"
flag "github.com/spf13/pflag"
Expand All @@ -18,6 +19,7 @@ import (
var (
requestURL string
authTokenFlag string
timeoutFlag time.Duration
)

func RPCFlags() *flag.FlagSet {
Expand All @@ -37,6 +39,13 @@ func RPCFlags() *flag.FlagSet {
"Authorization token",
)

fset.DurationVar(
&timeoutFlag,
"timeout",
0,
"Timeout for RPC requests (e.g. 30s, 1m)",
)

storeFlag := NodeFlags().Lookup(nodeStoreFlag)
fset.AddFlag(storeFlag)
return fset
Expand Down Expand Up @@ -73,7 +82,12 @@ func InitClient(cmd *cobra.Command, _ []string) error {
}
}

client, err := rpc.NewClient(cmd.Context(), requestURL, authTokenFlag)
var opts []rpc.RPCClientOption
if timeoutFlag > 0 {
opts = append(opts, rpc.WithTimeout(timeoutFlag))
}

client, err := rpc.NewClient(cmd.Context(), requestURL, authTokenFlag, opts...)
sebasti810 marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return err
}
Expand Down