fix race condition in incorrectly shared state in MultiSearch
When performing a MultiSearch, we create child SearchRequests from the original SearchRequest. In doing so we copy many fields. But, copying of the SortOrder was incorrect, as this contains state, and distint SortOrder objects must be used. This change introduces a Copy() method to the SearchSort interface, and to the SortOrder types. MultiSearch now creates a new copy of the SortOrder for each child request.
This commit is contained in:
parent
957812369d
commit
a78e632bd6
|
@ -432,7 +432,7 @@ func createChildSearchRequest(req *SearchRequest) *SearchRequest {
|
|||
Fields: req.Fields,
|
||||
Facets: req.Facets,
|
||||
Explain: req.Explain,
|
||||
Sort: req.Sort,
|
||||
Sort: req.Sort.Copy(),
|
||||
IncludeLocations: req.IncludeLocations,
|
||||
}
|
||||
return &rv
|
||||
|
|
|
@ -36,6 +36,8 @@ type SearchSort interface {
|
|||
RequiresDocID() bool
|
||||
RequiresScoring() bool
|
||||
RequiresFields() []string
|
||||
|
||||
Copy() SearchSort
|
||||
}
|
||||
|
||||
func ParseSearchSortObj(input map[string]interface{}) (SearchSort, error) {
|
||||
|
@ -205,6 +207,14 @@ func (so SortOrder) UpdateVisitor(field string, term []byte) {
|
|||
}
|
||||
}
|
||||
|
||||
func (so SortOrder) Copy() SortOrder {
|
||||
rv := make(SortOrder, len(so))
|
||||
for i, soi := range so {
|
||||
rv[i] = soi.Copy()
|
||||
}
|
||||
return rv
|
||||
}
|
||||
|
||||
// Compare will compare two document matches using the specified sort order
|
||||
// if both are numbers, we avoid converting back to term
|
||||
func (so SortOrder) Compare(cachedScoring, cachedDesc []bool, i, j *DocumentMatch) int {
|
||||
|
@ -475,6 +485,12 @@ func (s *SortField) MarshalJSON() ([]byte, error) {
|
|||
return json.Marshal(sfm)
|
||||
}
|
||||
|
||||
func (s *SortField) Copy() SearchSort {
|
||||
var rv SortField
|
||||
rv = *s
|
||||
return &rv
|
||||
}
|
||||
|
||||
// SortDocID will sort results by the document identifier
|
||||
type SortDocID struct {
|
||||
Desc bool
|
||||
|
@ -512,6 +528,12 @@ func (s *SortDocID) MarshalJSON() ([]byte, error) {
|
|||
return json.Marshal("_id")
|
||||
}
|
||||
|
||||
func (s *SortDocID) Copy() SearchSort {
|
||||
var rv SortDocID
|
||||
rv = *s
|
||||
return &rv
|
||||
}
|
||||
|
||||
// SortScore will sort results by the document match score
|
||||
type SortScore struct {
|
||||
Desc bool
|
||||
|
@ -549,6 +571,12 @@ func (s *SortScore) MarshalJSON() ([]byte, error) {
|
|||
return json.Marshal("_score")
|
||||
}
|
||||
|
||||
func (s *SortScore) Copy() SearchSort {
|
||||
var rv SortScore
|
||||
rv = *s
|
||||
return &rv
|
||||
}
|
||||
|
||||
var maxDistance = string(numeric.MustNewPrefixCodedInt64(math.MaxInt64, 0))
|
||||
|
||||
// NewSortGeoDistance creates SearchSort instance for sorting documents by
|
||||
|
@ -675,3 +703,9 @@ func (s *SortGeoDistance) MarshalJSON() ([]byte, error) {
|
|||
|
||||
return json.Marshal(sfm)
|
||||
}
|
||||
|
||||
func (s *SortGeoDistance) Copy() SearchSort {
|
||||
var rv SortGeoDistance
|
||||
rv = *s
|
||||
return &rv
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue