github.com/grafana/pyroscope@v1.18.0/pkg/metastore/tenant_service.go (about)

     1  package metastore
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/go-kit/log"
     7  	"github.com/opentracing/opentracing-go"
     8  	"github.com/opentracing/opentracing-go/ext"
     9  	"go.etcd.io/bbolt"
    10  	"google.golang.org/grpc/codes"
    11  	"google.golang.org/grpc/status"
    12  
    13  	metastorev1 "github.com/grafana/pyroscope/api/gen/proto/go/metastore/v1"
    14  	"github.com/grafana/pyroscope/pkg/metastore/raftnode"
    15  )
    16  
    17  type TenantIndex interface {
    18  	GetTenants(tx *bbolt.Tx) []string
    19  	GetTenantStats(tx *bbolt.Tx, tenant string) *metastorev1.TenantStats
    20  }
    21  
    22  type TenantService struct {
    23  	metastorev1.TenantServiceServer
    24  
    25  	logger log.Logger
    26  	state  State
    27  	index  TenantIndex
    28  }
    29  
    30  func NewTenantService(
    31  	logger log.Logger,
    32  	state State,
    33  	index TenantIndex,
    34  ) *TenantService {
    35  	return &TenantService{
    36  		logger: logger,
    37  		state:  state,
    38  		index:  index,
    39  	}
    40  }
    41  
    42  func (svc *TenantService) GetTenants(
    43  	ctx context.Context,
    44  	_ *metastorev1.GetTenantsRequest,
    45  ) (resp *metastorev1.GetTenantsResponse, err error) {
    46  	span, ctx := opentracing.StartSpanFromContext(ctx, "TenantService.GetTenants")
    47  	defer func() {
    48  		if err != nil {
    49  			ext.LogError(span, err)
    50  		}
    51  		span.Finish()
    52  	}()
    53  
    54  	read := func(tx *bbolt.Tx, _ raftnode.ReadIndex) {
    55  		resp = &metastorev1.GetTenantsResponse{TenantIds: svc.index.GetTenants(tx)}
    56  	}
    57  	if readErr := svc.state.ConsistentRead(ctx, read); readErr != nil {
    58  		return nil, status.Error(codes.Unavailable, readErr.Error())
    59  	}
    60  	span.SetTag("tenant_count", len(resp.GetTenantIds()))
    61  	return resp, err
    62  }
    63  
    64  func (svc *TenantService) GetTenant(
    65  	ctx context.Context,
    66  	req *metastorev1.GetTenantRequest,
    67  ) (resp *metastorev1.GetTenantResponse, err error) {
    68  	span, ctx := opentracing.StartSpanFromContext(ctx, "TenantService.GetTenant")
    69  	defer func() {
    70  		if err != nil {
    71  			ext.LogError(span, err)
    72  		}
    73  		span.Finish()
    74  	}()
    75  
    76  	span.SetTag("tenant_id", req.GetTenantId())
    77  
    78  	read := func(tx *bbolt.Tx, _ raftnode.ReadIndex) {
    79  		resp = &metastorev1.GetTenantResponse{Stats: svc.index.GetTenantStats(tx, req.TenantId)}
    80  	}
    81  	if readErr := svc.state.ConsistentRead(ctx, read); readErr != nil {
    82  		return nil, status.Error(codes.Unavailable, readErr.Error())
    83  	}
    84  	if stats := resp.GetStats(); stats != nil {
    85  		span.SetTag("data_ingested", stats.GetDataIngested())
    86  		span.SetTag("oldest_profile_time", stats.GetOldestProfileTime())
    87  		span.SetTag("newest_profile_time", stats.GetNewestProfileTime())
    88  	} else {
    89  		span.SetTag("data_ingested", false)
    90  	}
    91  	return resp, err
    92  }
    93  
    94  func (svc *TenantService) DeleteTenant(
    95  	context.Context,
    96  	*metastorev1.DeleteTenantRequest,
    97  ) (*metastorev1.DeleteTenantResponse, error) {
    98  	// TODO(kolesnikovae): Implement.
    99  	return new(metastorev1.DeleteTenantResponse), nil
   100  }