0
0
Fork 0

more careful Close()'ing and cleanup of searchers

From diagnosing a recent issue where the termSearchersFinished stats
were incorrectly tracked, I ended up scouring the Close() / cleanup
codepaths.

This change takes more care in Close()'ing child searchers, especially
in error situations.  This can be important to allow underlying
kvstore's to release resources.
This commit is contained in:
Steve Yen 2016-09-29 16:51:42 -07:00
parent 30b5cb86d1
commit a9cb8779c3
11 changed files with 57 additions and 23 deletions

View File

@ -48,6 +48,11 @@ func (q *ConjunctionQuery) Searcher(i index.IndexReader, m mapping.IndexMapping,
var err error
ss[in], err = conjunct.Searcher(i, m, explain)
if err != nil {
for _, searcher := range ss {
if searcher != nil {
_ = searcher.Close()
}
}
return nil, err
}
}

View File

@ -54,6 +54,11 @@ func (q *DisjunctionQuery) Searcher(i index.IndexReader, m mapping.IndexMapping,
var err error
ss[in], err = disjunct.Searcher(i, m, explain)
if err != nil {
for _, searcher := range ss {
if searcher != nil {
_ = searcher.Close()
}
}
return nil, err
}
}

View File

@ -345,23 +345,24 @@ func (s *BooleanSearcher) Count() uint64 {
}
func (s *BooleanSearcher) Close() error {
var err0, err1, err2 error
if s.mustSearcher != nil {
err := s.mustSearcher.Close()
if err != nil {
return err
}
err0 = s.mustSearcher.Close()
}
if s.shouldSearcher != nil {
err := s.shouldSearcher.Close()
if err != nil {
return err
}
err1 = s.shouldSearcher.Close()
}
if s.mustNotSearcher != nil {
err := s.mustNotSearcher.Close()
if err != nil {
return err
}
err2 = s.mustNotSearcher.Close()
}
if err0 != nil {
return err0
}
if err1 != nil {
return err1
}
if err2 != nil {
return err2
}
return nil
}

View File

@ -204,14 +204,14 @@ func (s *ConjunctionSearcher) Count() uint64 {
return sum
}
func (s *ConjunctionSearcher) Close() error {
func (s *ConjunctionSearcher) Close() (rv error) {
for _, searcher := range s.searchers {
err := searcher.Close()
if err != nil {
return err
if err != nil && rv == nil {
rv = err
}
}
return nil
return rv
}
func (s *ConjunctionSearcher) Min() int {

View File

@ -215,14 +215,14 @@ func (s *DisjunctionSearcher) Count() uint64 {
return sum
}
func (s *DisjunctionSearcher) Close() error {
func (s *DisjunctionSearcher) Close() (rv error) {
for _, searcher := range s.searchers {
err := searcher.Close()
if err != nil {
return err
if err != nil && rv == nil {
rv = err
}
}
return nil
return rv
}
func (s *DisjunctionSearcher) Min() int {

View File

@ -76,7 +76,7 @@ func (s *DocIDSearcher) Advance(ctx *search.SearchContext, ID index.IndexInterna
}
func (s *DocIDSearcher) Close() error {
return nil
return s.reader.Close()
}
func (s *DocIDSearcher) Min() int {

View File

@ -39,10 +39,15 @@ func NewFuzzySearcher(indexReader index.IndexReader, term string, prefix, fuzzin
// enumerate all the terms in the range
qsearchers := make([]search.Searcher, 0, len(candidateTerms))
qsearchersClose := func() {
for _, searcher := range qsearchers {
_ = searcher.Close()
}
}
for _, cterm := range candidateTerms {
qsearcher, err := NewTermSearcher(indexReader, cterm, field, boost, explain)
if err != nil {
qsearchersClose()
return nil, err
}
qsearchers = append(qsearchers, qsearcher)
@ -51,6 +56,7 @@ func NewFuzzySearcher(indexReader index.IndexReader, term string, prefix, fuzzin
// build disjunction searcher of these ranges
searcher, err := NewDisjunctionSearcher(indexReader, qsearchers, 0, explain)
if err != nil {
qsearchersClose()
return nil, err
}

View File

@ -29,6 +29,7 @@ func NewMatchAllSearcher(indexReader index.IndexReader, boost float64, explain b
}
count, err := indexReader.DocCount()
if err != nil {
_ = reader.Close()
return nil, err
}
scorer := scorers.NewConstantScorer(1.0, boost, explain)

View File

@ -62,16 +62,25 @@ func NewNumericRangeSearcher(indexReader index.IndexReader, min *float64, max *f
}
// enumerate all the terms in the range
qsearchers := make([]search.Searcher, len(terms))
qsearchersClose := func() {
for _, searcher := range qsearchers {
if searcher != nil {
_ = searcher.Close()
}
}
}
for i, term := range terms {
var err error
qsearchers[i], err = NewTermSearcher(indexReader, string(term), field, boost, explain)
if err != nil {
qsearchersClose()
return nil, err
}
}
// build disjunction searcher of these ranges
searcher, err := NewDisjunctionSearcher(indexReader, qsearchers, 0, explain)
if err != nil {
qsearchersClose()
return nil, err
}
return &NumericRangeSearcher{

View File

@ -41,10 +41,15 @@ func NewRegexpSearcher(indexReader index.IndexReader, pattern *regexp.Regexp, fi
// enumerate all the terms in the range
qsearchers := make([]search.Searcher, 0, len(candidateTerms))
qsearchersClose := func() {
for _, searcher := range qsearchers {
_ = searcher.Close()
}
}
for _, cterm := range candidateTerms {
qsearcher, err := NewTermSearcher(indexReader, cterm, field, boost, explain)
if err != nil {
qsearchersClose()
return nil, err
}
qsearchers = append(qsearchers, qsearcher)
@ -53,6 +58,7 @@ func NewRegexpSearcher(indexReader index.IndexReader, pattern *regexp.Regexp, fi
// build disjunction searcher of these ranges
searcher, err := NewDisjunctionSearcher(indexReader, qsearchers, 0, explain)
if err != nil {
qsearchersClose()
return nil, err
}

View File

@ -32,6 +32,7 @@ func NewTermSearcher(indexReader index.IndexReader, term string, field string, b
}
count, err := indexReader.DocCount()
if err != nil {
_ = reader.Close()
return nil, err
}
scorer := scorers.NewTermQueryScorer(term, field, boost, count, reader.Count(), explain)