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  }`