diff --git a/retrieval/scrape.go b/retrieval/scrape.go index 50400297e..46ccb7827 100644 --- a/retrieval/scrape.go +++ b/retrieval/scrape.go @@ -567,7 +567,7 @@ loop: samplesScraped[sl.lsetCache[ref].str] = sl.lsetCache[ref].lset case storage.ErrNotFound: ok = false - case errSeriesDropped: + case errSeriesDropped, storage.ErrOutOfOrderSample, storage.ErrDuplicateSampleForTimestamp: continue default: break loop @@ -581,7 +581,7 @@ loop: // TODO(fabxc): also add a dropped-cache? switch err { case nil: - case errSeriesDropped: + case errSeriesDropped, storage.ErrOutOfOrderSample, storage.ErrDuplicateSampleForTimestamp: continue default: break loop diff --git a/retrieval/scrape_test.go b/retrieval/scrape_test.go index 4378b9f7b..266e8ae7a 100644 --- a/retrieval/scrape_test.go +++ b/retrieval/scrape_test.go @@ -653,6 +653,50 @@ func TestScrapeLoopAppendNoStalenessIfTimestamp(t *testing.T) { } +type errorAppender struct { + collectResultAppender +} + +func (app *errorAppender) Add(lset labels.Labels, t int64, v float64) (uint64, error) { + if lset.Get(model.MetricNameLabel) == "out_of_order" { + return 0, storage.ErrOutOfOrderSample + } else if lset.Get(model.MetricNameLabel) == "amend" { + return 0, storage.ErrDuplicateSampleForTimestamp + } + return app.collectResultAppender.Add(lset, t, v) +} + +func (app *errorAppender) AddFast(ref uint64, t int64, v float64) error { + return app.collectResultAppender.AddFast(ref, t, v) +} + +func TestScrapeLoopAppendGracefullyIfAmendOrOutOfOrder(t *testing.T) { + app := &errorAppender{} + sl := &scrapeLoop{ + appender: func() storage.Appender { return app }, + reportAppender: func() storage.Appender { return nopAppender{} }, + refCache: map[string]uint64{}, + lsetCache: map[uint64]lsetCacheEntry{}, + } + + now := time.Unix(1, 0) + _, _, err := sl.append([]byte("out_of_order 1\namend 1\nnormal 1\n"), now) + if err != nil { + t.Fatalf("Unexpected append error: %s", err) + } + want := []sample{ + { + metric: labels.FromStrings(model.MetricNameLabel, "normal"), + t: timestamp.FromTime(now), + v: 1, + }, + } + if !reflect.DeepEqual(want, app.result) { + t.Fatalf("Appended samples not as expected. Wanted: %+v Got: %+v", want, app.result) + } + +} + func TestTargetScraperScrapeOK(t *testing.T) { const ( configTimeout = 1500 * time.Millisecond