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 }