Skip to content

Commit

Permalink
fix issue thanos-io#4777: panic when warn is nil
Browse files Browse the repository at this point in the history
Signed-off-by: ian woolf <btw515wolf2@gmail.com>
  • Loading branch information
ianwoolf committed Oct 28, 2021
1 parent 24602c4 commit de6822d
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 2 deletions.
15 changes: 13 additions & 2 deletions pkg/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,15 @@ func GetInstr(
if data, warnings, err := f(r); err != nil {
RespondError(w, err, data)
} else if data != nil {
Respond(w, data, warnings)
var _warnings []error
for i := range warnings {
if warnings[i] == nil {
level.Error(logger).Log("unexpected nil warning", "path", r.RequestURI, "warings", warnings)
continue
}
_warnings = append(_warnings, warnings[i])
}
respond(w, data, _warnings)
} else {
w.WriteHeader(http.StatusNoContent)
}
Expand All @@ -230,7 +238,7 @@ func GetInstr(
return instr
}

func Respond(w http.ResponseWriter, data interface{}, warnings []error) {
func respond(w http.ResponseWriter, data interface{}, warnings []error) {
w.Header().Set("Content-Type", "application/json")
if len(warnings) > 0 {
w.Header().Set("Cache-Control", "no-store")
Expand All @@ -242,6 +250,9 @@ func Respond(w http.ResponseWriter, data interface{}, warnings []error) {
Data: data,
}
for _, warn := range warnings {
if warn == nil {
continue
}
resp.Warnings = append(resp.Warnings, warn.Error())
}
_ = json.NewEncoder(w).Encode(resp)
Expand Down
4 changes: 4 additions & 0 deletions pkg/exemplars/exemplars.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package exemplars
import (
"context"
"sort"
"sync"

"github.com/pkg/errors"
"github.com/prometheus/prometheus/storage"
Expand All @@ -32,6 +33,7 @@ type GRPCClient struct {

type exemplarsServer struct {
// This field just exist to pseudo-implement the unused methods of the interface.
sync.RWMutex
exemplarspb.Exemplars_ExemplarsServer
ctx context.Context

Expand All @@ -40,6 +42,8 @@ type exemplarsServer struct {
}

func (srv *exemplarsServer) Send(res *exemplarspb.ExemplarsResponse) error {
srv.Lock()
defer srv.Unlock()
if res.GetWarning() != "" {
srv.warnings = append(srv.warnings, errors.New(res.GetWarning()))
return nil
Expand Down
25 changes: 25 additions & 0 deletions pkg/exemplars/exemplars_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ package exemplars
import (
"testing"

"github.com/pkg/errors"
"github.com/prometheus/prometheus/pkg/labels"
"github.com/thanos-io/thanos/pkg/exemplars/exemplarspb"
"github.com/thanos-io/thanos/pkg/store/labelpb"
"github.com/thanos-io/thanos/pkg/testutil"
Expand All @@ -15,6 +17,29 @@ func TestMain(m *testing.M) {
testutil.TolerantVerifyLeakMain(m)
}

func TestExemplarsServerSendDataRace(t *testing.T) {
es := &exemplarsServer{}

res := []*exemplarspb.ExemplarsResponse{
exemplarspb.NewExemplarsResponse(&exemplarspb.ExemplarData{
SeriesLabels: labelpb.ZLabelSet{Labels: labelpb.ZLabelsFromPromLabels(labels.FromMap(map[string]string{"__name__": "http_request_duration_bucket"}))},
Exemplars: []*exemplarspb.Exemplar{{Value: 1}},
}),
exemplarspb.NewWarningExemplarsResponse(errors.New("warning from client1")), exemplarspb.NewExemplarsResponse(&exemplarspb.ExemplarData{
SeriesLabels: labelpb.ZLabelSet{Labels: labelpb.ZLabelsFromPromLabels(labels.FromMap(map[string]string{"__name__": "http_request_duration_bucket"}))},
Exemplars: []*exemplarspb.Exemplar{{Value: 1}},
}),
exemplarspb.NewWarningExemplarsResponse(errors.New("warning from client2")), exemplarspb.NewExemplarsResponse(&exemplarspb.ExemplarData{
SeriesLabels: labelpb.ZLabelSet{Labels: labelpb.ZLabelsFromPromLabels(labels.FromMap(map[string]string{"__name__": "http_request_duration_bucket"}))},
Exemplars: []*exemplarspb.Exemplar{{Value: 1}},
}),
}

for i := range res {
go es.Send(res[i])
}
}

func TestDedupExemplarsResponse(t *testing.T) {
for _, tc := range []struct {
name string
Expand Down

0 comments on commit de6822d

Please sign in to comment.