From ea817e169b7f7bc17206285e6bac27fea69f2f2d Mon Sep 17 00:00:00 2001 From: Fabian Reinartz Date: Fri, 20 Oct 2017 09:43:52 +0200 Subject: [PATCH] Return nop iterator for invalid chunk references --- chunks/chunk.go | 11 +++++++++++ head.go | 6 ++++++ 2 files changed, 17 insertions(+) diff --git a/chunks/chunk.go b/chunks/chunk.go index 181693fae..4d298041e 100644 --- a/chunks/chunk.go +++ b/chunks/chunk.go @@ -69,6 +69,17 @@ type Iterator interface { Next() bool } +// NewNopIterator returns a new chunk iterator that does not hold any data. +func NewNopIterator() Iterator { + return nopIterator{} +} + +type nopIterator struct{} + +func (nopIterator) At() (int64, float64) { return 0, 0 } +func (nopIterator) Next() bool { return false } +func (nopIterator) Err() error { return nil } + type Pool interface { Put(Chunk) error Get(e Encoding, b []byte) (Chunk, error) diff --git a/head.go b/head.go index 0aeaef5a6..8182fb4b5 100644 --- a/head.go +++ b/head.go @@ -1270,6 +1270,12 @@ func computeChunkEndTime(start, cur, max int64) int64 { func (s *memSeries) iterator(id int) chunks.Iterator { c := s.chunk(id) + // TODO(fabxc): Work around! A querier may have retrieved a pointer to a series' chunk, + // which got then garbage collected before it got accessed. + // We must ensure to not garbage collect as long as any readers still hold a reference. + if c == nil { + return chunks.NewNopIterator() + } if id-s.firstChunkID < len(s.chunks)-1 { return c.chunk.Iterator()