github.com/grafana/pyroscope@v1.18.0/pkg/frontend/frontend_diff.go (about)

     1  package frontend
     2  
     3  import (
     4  	"context"
     5  
     6  	"connectrpc.com/connect"
     7  	"github.com/grafana/dskit/tenant"
     8  	"golang.org/x/sync/errgroup"
     9  
    10  	querierv1 "github.com/grafana/pyroscope/api/gen/proto/go/querier/v1"
    11  	"github.com/grafana/pyroscope/api/gen/proto/go/querier/v1/querierv1connect"
    12  	phlaremodel "github.com/grafana/pyroscope/pkg/model"
    13  	"github.com/grafana/pyroscope/pkg/util/connectgrpc"
    14  	"github.com/grafana/pyroscope/pkg/validation"
    15  )
    16  
    17  func (f *Frontend) Diff(
    18  	ctx context.Context,
    19  	c *connect.Request[querierv1.DiffRequest],
    20  ) (*connect.Response[querierv1.DiffResponse], error) {
    21  	ctx = connectgrpc.WithProcedure(ctx, querierv1connect.QuerierServiceDiffProcedure)
    22  	g, ctx := errgroup.WithContext(ctx)
    23  	tenantIDs, err := tenant.TenantIDs(ctx)
    24  	if err != nil {
    25  		return nil, connect.NewError(connect.CodeInvalidArgument, err)
    26  	}
    27  
    28  	if c.Msg.Left == nil {
    29  		c.Msg.Left = &querierv1.SelectMergeStacktracesRequest{}
    30  	}
    31  
    32  	if c.Msg.Right == nil {
    33  		c.Msg.Right = &querierv1.SelectMergeStacktracesRequest{}
    34  	}
    35  
    36  	maxNodes := c.Msg.Left.GetMaxNodes()
    37  	if n := c.Msg.Right.GetMaxNodes(); n > maxNodes {
    38  		maxNodes = n
    39  	}
    40  	maxNodes, err = validation.ValidateMaxNodes(f.limits, tenantIDs, maxNodes)
    41  	if err != nil {
    42  		return nil, connect.NewError(connect.CodeInvalidArgument, err)
    43  	}
    44  	c.Msg.Left.MaxNodes = &maxNodes
    45  	c.Msg.Right.MaxNodes = &maxNodes
    46  
    47  	var left, right *phlaremodel.Tree
    48  	g.Go(func() error {
    49  		var leftErr error
    50  		left, leftErr = f.selectMergeStacktracesTree(ctx, connect.NewRequest(c.Msg.Left))
    51  		return leftErr
    52  	})
    53  	g.Go(func() error {
    54  		var rightErr error
    55  		right, rightErr = f.selectMergeStacktracesTree(ctx, connect.NewRequest(c.Msg.Right))
    56  		return rightErr
    57  	})
    58  	if err = g.Wait(); err != nil {
    59  		return nil, err
    60  	}
    61  
    62  	diff, err := phlaremodel.NewFlamegraphDiff(left, right, maxNodes)
    63  	if err != nil {
    64  		return nil, connect.NewError(connect.CodeInvalidArgument, err)
    65  	}
    66  
    67  	return connect.NewResponse(&querierv1.DiffResponse{Flamegraph: diff}), nil
    68  }