fix adjust last points avoid influence earlier value (#606)

This commit is contained in:
faceair 2020-07-05 09:56:54 -05:00 committed by Aliaksandr Valialkin
parent 6f1d926698
commit 17f175ff5a
2 changed files with 140 additions and 7 deletions

View File

@ -878,7 +878,7 @@ func queryRangeHandler(at *auth.Token, w http.ResponseWriter, query string, star
}
queryOffset := getLatencyOffsetMilliseconds()
if ct-end < queryOffset {
result = adjustLastPoints(result)
result = adjustLastPoints(result, ct, queryOffset)
}
// Remove NaN values as Prometheus does.
@ -925,7 +925,7 @@ var queryRangeDuration = metrics.NewSummary(`vm_request_duration_seconds{path="/
// adjustLastPoints substitutes the last point values with the previous
// point values, since the last points may contain garbage.
func adjustLastPoints(tss []netstorage.Result) []netstorage.Result {
func adjustLastPoints(tss []netstorage.Result, ct, queryOffset int64) []netstorage.Result {
if len(tss) == 0 {
return nil
}
@ -951,12 +951,18 @@ func adjustLastPoints(tss []netstorage.Result) []netstorage.Result {
// with the previous values for each timeseries.
for i := range tss {
values := tss[i].Values
for j := 0; j < 2; j++ {
idx := lastNonNaNIdx + j
if idx <= 0 || idx >= len(values) || math.IsNaN(values[idx-1]) {
continue
if lastNonNaNIdx > len(values) {
continue
}
end := tss[i].Timestamps[lastNonNaNIdx]
if ct-end < queryOffset {
for j := 1; j < 3; j++ {
idx := lastNonNaNIdx + j
if idx <= 0 || idx >= len(values) || math.IsNaN(values[idx-1]) {
continue
}
values[idx] = values[idx-1]
}
values[idx] = values[idx-1]
}
}
return tss

View File

@ -113,3 +113,130 @@ func TestGetTimeError(t *testing.T) {
f("-292273086-05-16T16:47:07Z")
f("292277025-08-18T07:12:54.999999998Z")
}
func TestAdjustLastPoints(t *testing.T) {
f := func(tss []netstorage.Result, ct, queryOffset int64, tssExpected []netstorage.Result) {
t.Helper()
tss = adjustLastPoints(tss, ct, queryOffset)
for i, ts := range tss {
for j, value := range ts.Values {
expectedValue := tssExpected[i].Values[j]
if math.IsNaN(expectedValue) {
if !math.IsNaN(value) {
t.Fatalf("unexpected result; got %v; want nan", value)
}
} else if expectedValue != value {
t.Fatalf("unexpected result; got %v; want %v", value, expectedValue)
}
}
if !reflect.DeepEqual(ts.Timestamps, tssExpected[i].Timestamps) {
t.Fatalf("unexpected result; got %v; want %v", tss, tssExpected)
}
}
}
nan := math.NaN()
f(nil, 500, 300, nil)
f([]netstorage.Result{
{
Timestamps: []int64{100, 200, 300, 400, 500},
Values: []float64{1, 2, 3, 4, nan},
},
{
Timestamps: []int64{100, 200, 300, 400, 500},
Values: []float64{1, 2, 3, nan, nan},
},
}, 500, 300, []netstorage.Result{
{
Timestamps: []int64{100, 200, 300, 400, 500},
Values: []float64{1, 2, 3, 4, 4},
},
{
Timestamps: []int64{100, 200, 300, 400, 500},
Values: []float64{1, 2, 3, nan, nan},
},
})
f([]netstorage.Result{
{
Timestamps: []int64{100, 200, 300, 400, 500},
Values: []float64{1, 2, 3, nan, nan},
},
{
Timestamps: []int64{100, 200, 300, 400, 500},
Values: []float64{1, 2, nan, nan, nan},
},
}, 500, 300, []netstorage.Result{
{
Timestamps: []int64{100, 200, 300, 400, 500},
Values: []float64{1, 2, 3, 3, 3},
},
{
Timestamps: []int64{100, 200, 300, 400, 500},
Values: []float64{1, 2, nan, nan, nan},
},
})
f([]netstorage.Result{
{
Timestamps: []int64{100, 200, 300, 400, 500},
Values: []float64{1, 2, nan, nan, nan},
},
{
Timestamps: []int64{100, 200, 300, 400, 500},
Values: []float64{1, nan, nan, nan, nan},
},
}, 500, 300, []netstorage.Result{
{
Timestamps: []int64{100, 200, 300, 400, 500},
Values: []float64{1, 2, nan, nan, nan},
},
{
Timestamps: []int64{100, 200, 300, 400, 500},
Values: []float64{1, nan, nan, nan, nan},
},
})
f([]netstorage.Result{
{
Timestamps: []int64{100, 200, 300, 400, 500},
Values: []float64{1, 2, 3, 4, nan},
},
{
Timestamps: []int64{100, 200, 300, 400},
Values: []float64{1, 2, 3, 4},
},
}, 500, 300, []netstorage.Result{
{
Timestamps: []int64{100, 200, 300, 400, 500},
Values: []float64{1, 2, 3, 4, 4},
},
{
Timestamps: []int64{100, 200, 300, 400},
Values: []float64{1, 2, 3, 4},
},
})
f([]netstorage.Result{
{
Timestamps: []int64{100, 200, 300, 400, 500},
Values: []float64{1, 2, 3, nan, nan},
},
{
Timestamps: []int64{100, 200, 300},
Values: []float64{1, 2, nan},
},
}, 500, 300, []netstorage.Result{
{
Timestamps: []int64{100, 200, 300, 400, 500},
Values: []float64{1, 2, 3, 3, 3},
},
{
Timestamps: []int64{100, 200, 300},
Values: []float64{1, 2, nan},
},
})
}