Skip to content

Commit b52f25b

Browse files
author
pawarpranav83
committed
Added negative offset check for caching queries
Signed-off-by: pawarpranav83 <[email protected]>
1 parent a1b1954 commit b52f25b

File tree

3 files changed

+82
-0
lines changed

3 files changed

+82
-0
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Changelog
22

33
## master / unreleased
4+
* [BUGFIX] Query Frontend: queries with negative offset should check whether it is cacheable or not #5719
45
* [CHANGE] Azure Storage: Upgraded objstore dependency and support Azure Workload Identity Authentication. Added `connection_string` to support authenticating via SAS token. Marked `msi_resource` config as deprecating. #5645
56
* [CHANGE] Store Gateway: Add a new fastcache based inmemory index cache. #5619
67
* [CHANGE] Index Cache: Multi level cache backfilling operation becomes async. Added `-blocks-storage.bucket-store.index-cache.multilevel.max-async-concurrency` and `-blocks-storage.bucket-store.index-cache.multilevel.max-async-buffer-size` configs and metric `cortex_store_multilevel_index_cache_backfill_dropped_items_total` for number of dropped items. #5661

pkg/querier/tripperware/queryrange/results_cache.go

+42
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,9 @@ func (s resultsCache) shouldCacheResponse(ctx context.Context, req tripperware.R
265265
if !s.isAtModifierCachable(ctx, req, maxCacheTime) {
266266
return false
267267
}
268+
if !s.isOffsetCachable(ctx, req) {
269+
return false
270+
}
268271

269272
return true
270273
}
@@ -321,6 +324,45 @@ func (s resultsCache) isAtModifierCachable(ctx context.Context, r tripperware.Re
321324
return atModCachable
322325
}
323326

327+
var negativeOffset = errors.New("negative offset")
328+
329+
func (s resultsCache) isOffsetCachable(ctx context.Context, r tripperware.Request) bool {
330+
query := r.GetQuery()
331+
if !strings.Contains(query, "offset") {
332+
return true
333+
}
334+
expr, err := parser.ParseExpr(query)
335+
if err != nil {
336+
level.Warn(util_log.WithContext(ctx, s.logger)).Log("msg", "failed to parse query, considering @ modifier as not cachable", "query", query, "err", err)
337+
return false
338+
}
339+
340+
offsetCachable := true
341+
parser.Inspect(expr, func(n parser.Node, _ []parser.Node) error {
342+
switch e := n.(type) {
343+
case *parser.VectorSelector:
344+
if e.OriginalOffset < 0 {
345+
offsetCachable = false
346+
return negativeOffset
347+
}
348+
case *parser.MatrixSelector:
349+
offset := e.VectorSelector.(*parser.VectorSelector).OriginalOffset
350+
if offset < 0 {
351+
offsetCachable = false
352+
return negativeOffset
353+
}
354+
case *parser.SubqueryExpr:
355+
if e.OriginalOffset < 0 {
356+
offsetCachable = false
357+
return negativeOffset
358+
}
359+
}
360+
return nil
361+
})
362+
363+
return offsetCachable
364+
}
365+
324366
func getHeaderValuesWithName(r tripperware.Response, headerName string) (headerValues []string) {
325367
for name, hv := range r.HTTPHeaders() {
326368
if name != headerName {

pkg/querier/tripperware/queryrange/results_cache_test.go

+39
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,45 @@ func TestShouldCache(t *testing.T) {
416416
input: tripperware.Response(&PrometheusResponse{}),
417417
expected: false,
418418
},
419+
// offset on vector selectors.
420+
{
421+
name: "positive offset on vector selector",
422+
request: &PrometheusRequest{Query: "metric offset 10ms", End: 125000},
423+
input: tripperware.Response(&PrometheusResponse{}),
424+
expected: true,
425+
},
426+
{
427+
name: "negative offset on vector selector",
428+
request: &PrometheusRequest{Query: "metric offset -10ms", End: 125000},
429+
input: tripperware.Response(&PrometheusResponse{}),
430+
expected: false,
431+
},
432+
// offset on matrix selectors.
433+
{
434+
name: "positive offset on matrix selector",
435+
request: &PrometheusRequest{Query: "rate(metric[5m] offset 10ms)", End: 125000},
436+
input: tripperware.Response(&PrometheusResponse{}),
437+
expected: true,
438+
},
439+
{
440+
name: "negative offset on matrix selector",
441+
request: &PrometheusRequest{Query: "rate(metric[5m] offset -10ms)", End: 125000},
442+
input: tripperware.Response(&PrometheusResponse{}),
443+
expected: false,
444+
},
445+
// offset on subqueries.
446+
{
447+
name: "positive offset on subqueries",
448+
request: &PrometheusRequest{Query: "sum_over_time(rate(metric[1m])[10m:1m] offset 10ms)", End: 125000},
449+
input: tripperware.Response(&PrometheusResponse{}),
450+
expected: true,
451+
},
452+
{
453+
name: "negative offset on subqueries",
454+
request: &PrometheusRequest{Query: "sum_over_time(rate(metric[1m])[10m:1m] offset -10ms)", End: 125000},
455+
input: tripperware.Response(&PrometheusResponse{}),
456+
expected: false,
457+
},
419458
} {
420459
{
421460
t.Run(tc.name, func(t *testing.T) {

0 commit comments

Comments
 (0)