(pipelineRequest pipeline.Request)
| 71 | } |
| 72 | |
| 73 | func (s queryRangeSharder) RoundTrip(pipelineRequest pipeline.Request) (pipeline.Responses[combiner.PipelineResponse], error) { |
| 74 | r := pipelineRequest.HTTPRequest() |
| 75 | spanName := "frontend.QueryRangeSharder.range" |
| 76 | |
| 77 | if s.instantMode { |
| 78 | spanName = "frontend.QueryRangeSharder.instant" |
| 79 | } |
| 80 | |
| 81 | ctx, span := tracer.Start(r.Context(), spanName) |
| 82 | defer span.End() |
| 83 | |
| 84 | req, err := api.ParseQueryRangeRequest(r) |
| 85 | if err != nil { |
| 86 | return pipeline.NewBadRequest(err), nil |
| 87 | } |
| 88 | |
| 89 | req.SkipASTTransformations = mergeSkipASTTransformations(s.skipASTTransformations, req.SkipASTTransformations) |
| 90 | |
| 91 | expr, err := traceql.ParseNoOptimizations(req.Query) |
| 92 | if err != nil { |
| 93 | return pipeline.NewBadRequest(err), nil |
| 94 | } |
| 95 | |
| 96 | if expr.IsNoop() { |
| 97 | // Empty response |
| 98 | ch := make(chan pipeline.Request, 2) |
| 99 | close(ch) |
| 100 | return pipeline.NewAsyncSharderChan(ctx, s.cfg.ConcurrentRequests, ch, nil, s.next), nil |
| 101 | } |
| 102 | |
| 103 | tenantID, err := validation.ExtractValidTenantID(ctx) |
| 104 | if err != nil { |
| 105 | return pipeline.NewBadRequest(err), nil |
| 106 | } |
| 107 | |
| 108 | if req.Step == 0 { |
| 109 | return pipeline.NewBadRequest(errors.New("step must be greater than 0")), nil |
| 110 | } |
| 111 | |
| 112 | // calculate and enforce max search duration |
| 113 | // This is checked before alignment because we may need to read a larger |
| 114 | // range internally to satisfy the query. |
| 115 | maxDuration := s.maxDuration(tenantID) |
| 116 | if maxDuration != 0 && time.Duration(req.End-req.Start)*time.Nanosecond > maxDuration { |
| 117 | err = fmt.Errorf("metrics query time range exceeds the maximum allowed duration of %s", maxDuration) |
| 118 | return pipeline.NewBadRequest(err), nil |
| 119 | } |
| 120 | |
| 121 | traceql.AlignRequest(req) |
| 122 | |
| 123 | // Instant queries must not compute exemplars |
| 124 | if s.instantMode { |
| 125 | req.Exemplars = 0 |
| 126 | } |
| 127 | |
| 128 | // if a limit is being enforced, honor the request if it is less than the limit |
| 129 | // else set it to max limit |
| 130 | if s.cfg.MaxResponseSeries > 0 && (req.MaxSeries > uint32(s.cfg.MaxResponseSeries) || req.MaxSeries == 0) { |
nothing calls this directly
no test coverage detected