Skip to content

Commit fd62dbf

Browse files
ringbuffers: cleanup subquery logic (#631)
The ringbuffer should not be aware if its used in a subquery or not, thats an improper hierarchy. Its better if the subquery owns that logic. Signed-off-by: Michael Hoffmann <[email protected]>
1 parent e9123dc commit fd62dbf

File tree

3 files changed

+28
-32
lines changed

3 files changed

+28
-32
lines changed

execution/scan/subquery.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"github.com/thanos-io/promql-engine/query"
1717
"github.com/thanos-io/promql-engine/ringbuffer"
1818

19+
"github.com/prometheus/prometheus/model/histogram"
1920
"github.com/prometheus/prometheus/model/labels"
2021
)
2122

@@ -225,6 +226,24 @@ func (o *subqueryOperator) collect(v model.StepVector, mint int64) {
225226
if buffer.Len() > 0 && v.T < buffer.MaxT() {
226227
continue
227228
}
229+
// Set any "NotCounterReset" and "CounterReset" hints in native
230+
// histograms to "UnknownCounterReset" because we might
231+
// otherwise miss a counter reset happening in samples not
232+
// returned by the subquery, or we might over-detect counter
233+
// resets if the sample with a counter reset is returned
234+
// multiple times by a high-res subquery. This intentionally
235+
// does not attempt to be clever (like detecting if we are
236+
// really missing underlying samples or returning underlying
237+
// samples multiple times) because subqueries on counters are
238+
// inherently problematic WRT counter reset handling, so we
239+
// cannot really solve the problem for good. We only want to
240+
// avoid problems that happen due to the explicitly set counter
241+
// reset hints and go back to the behavior we already know from
242+
// float samples.
243+
switch s.CounterResetHint {
244+
case histogram.NotCounterReset, histogram.CounterReset:
245+
s.CounterResetHint = histogram.UnknownCounterReset
246+
}
228247
buffer.Push(v.T, ringbuffer.Value{H: s})
229248
}
230249
o.next.GetPool().PutStepVector(v)
@@ -249,7 +268,7 @@ func (o *subqueryOperator) initSeries(ctx context.Context) error {
249268
o.series = make([]labels.Labels, len(series))
250269
o.buffers = make([]*ringbuffer.GenericRingBuffer, len(series))
251270
for i := range o.buffers {
252-
o.buffers[i] = ringbuffer.New(ctx, 8, o.subQuery.Range.Milliseconds(), o.subQuery.Offset.Milliseconds(), o.call, true)
271+
o.buffers[i] = ringbuffer.New(ctx, 8, o.subQuery.Range.Milliseconds(), o.subQuery.Offset.Milliseconds(), o.call)
253272
}
254273
var b labels.ScratchBuilder
255274
for i, s := range series {

ringbuffer/generic.go

Lines changed: 6 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,9 @@ type Sample struct {
2323
}
2424

2525
type GenericRingBuffer struct {
26-
ctx context.Context
27-
items []Sample
28-
tail []Sample
29-
subquery bool
26+
ctx context.Context
27+
items []Sample
28+
tail []Sample
3029

3130
currentStep int64
3231
offset int64
@@ -35,19 +34,18 @@ type GenericRingBuffer struct {
3534
call FunctionCall
3635
}
3736

38-
func New(ctx context.Context, size int, selectRange, offset int64, call FunctionCall, subquery bool) *GenericRingBuffer {
39-
return NewWithExtLookback(ctx, size, selectRange, offset, 0, call, subquery)
37+
func New(ctx context.Context, size int, selectRange, offset int64, call FunctionCall) *GenericRingBuffer {
38+
return NewWithExtLookback(ctx, size, selectRange, offset, 0, call)
4039
}
4140

42-
func NewWithExtLookback(ctx context.Context, size int, selectRange, offset, extLookback int64, call FunctionCall, subquery bool) *GenericRingBuffer {
41+
func NewWithExtLookback(ctx context.Context, size int, selectRange, offset, extLookback int64, call FunctionCall) *GenericRingBuffer {
4342
return &GenericRingBuffer{
4443
ctx: ctx,
4544
items: make([]Sample, 0, size),
4645
selectRange: selectRange,
4746
offset: offset,
4847
extLookback: extLookback,
4948
call: call,
50-
subquery: subquery,
5149
}
5250
}
5351

@@ -93,28 +91,7 @@ func (r *GenericRingBuffer) Push(t int64, v Value) {
9391
if v.H != nil {
9492
if r.items[n].V.H == nil {
9593
h := v.H.Copy()
96-
if r.subquery {
97-
// Set any "NotCounterReset" and "CounterReset" hints in native
98-
// histograms to "UnknownCounterReset" because we might
99-
// otherwise miss a counter reset happening in samples not
100-
// returned by the subquery, or we might over-detect counter
101-
// resets if the sample with a counter reset is returned
102-
// multiple times by a high-res subquery. This intentionally
103-
// does not attempt to be clever (like detecting if we are
104-
// really missing underlying samples or returning underlying
105-
// samples multiple times) because subqueries on counters are
106-
// inherently problematic WRT counter reset handling, so we
107-
// cannot really solve the problem for good. We only want to
108-
// avoid problems that happen due to the explicitly set counter
109-
// reset hints and go back to the behavior we already know from
110-
// float samples.
111-
switch h.CounterResetHint {
112-
case histogram.NotCounterReset, histogram.CounterReset:
113-
h.CounterResetHint = histogram.UnknownCounterReset
114-
}
115-
}
11694
r.items[n].V.H = h
117-
11895
} else {
11996
v.H.CopyTo(r.items[n].V.H)
12097
}

storage/prometheus/matrix_selector.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,9 +281,9 @@ func (o *matrixSelector) newBuffer(ctx context.Context) ringbuffer.Buffer {
281281
}
282282

283283
if o.isExtFunction {
284-
return ringbuffer.NewWithExtLookback(ctx, 8, o.selectRange, o.offset, o.opts.ExtLookbackDelta.Milliseconds()-1, o.call, false)
284+
return ringbuffer.NewWithExtLookback(ctx, 8, o.selectRange, o.offset, o.opts.ExtLookbackDelta.Milliseconds()-1, o.call)
285285
}
286-
return ringbuffer.New(ctx, 8, o.selectRange, o.offset, o.call, false)
286+
return ringbuffer.New(ctx, 8, o.selectRange, o.offset, o.call)
287287

288288
}
289289

0 commit comments

Comments
 (0)