github.com/grafana/pyroscope@v1.18.0/pkg/querybackend/client/client.go (about) 1 package querybackendclient 2 3 import ( 4 "context" 5 "fmt" 6 "time" 7 8 "github.com/grafana/dskit/grpcclient" 9 "github.com/grafana/dskit/services" 10 "google.golang.org/grpc" 11 12 queryv1 "github.com/grafana/pyroscope/api/gen/proto/go/query/v1" 13 ) 14 15 type Client struct { 16 service services.Service 17 grpcClient queryv1.QueryBackendServiceClient 18 } 19 20 func New(address string, grpcClientConfig grpcclient.Config, timeout time.Duration, dialOpts ...grpc.DialOption) (*Client, error) { 21 conn, err := dial(address, grpcClientConfig, timeout, dialOpts...) 22 if err != nil { 23 return nil, err 24 } 25 var c Client 26 c.grpcClient = queryv1.NewQueryBackendServiceClient(conn) 27 c.service = services.NewIdleService(c.starting, c.stopping) 28 return &c, nil 29 } 30 31 func dial(address string, grpcClientConfig grpcclient.Config, timeout time.Duration, dialOpts ...grpc.DialOption) (*grpc.ClientConn, error) { 32 options, err := grpcClientConfig.DialOption(nil, nil, nil) 33 if err != nil { 34 return nil, err 35 } 36 // TODO: https://github.com/grpc/grpc-proto/blob/master/grpc/service_config/service_config.proto 37 serviceConfig := fmt.Sprintf(grpcServiceConfigTemplate, timeout.Seconds()) 38 options = append(options, 39 grpc.WithDefaultServiceConfig(serviceConfig), 40 grpc.WithMaxCallAttempts(500), 41 ) 42 options = append(options, dialOpts...) 43 return grpc.NewClient(address, options...) 44 } 45 46 func (b *Client) Service() services.Service { return b.service } 47 func (b *Client) starting(context.Context) error { return nil } 48 func (b *Client) stopping(error) error { return nil } 49 50 func (b *Client) Invoke(ctx context.Context, req *queryv1.InvokeRequest) (*queryv1.InvokeResponse, error) { 51 return b.grpcClient.Invoke(ctx, req) 52 } 53 54 const grpcServiceConfigTemplate = `{ 55 "loadBalancingPolicy":"round_robin", 56 "methodConfig": [{ 57 "name": [{"service": ""}], 58 "waitForReady": true, 59 "retryPolicy": { 60 "MaxAttempts": 500, 61 "InitialBackoff": "1s", 62 "MaxBackoff": "2s", 63 "BackoffMultiplier": 1.1, 64 "RetryableStatusCodes": [ 65 "UNAVAILABLE", 66 "RESOURCE_EXHAUSTED" 67 ] 68 }, 69 "timeout": "%.0fs" 70 }] 71 }`