Skip to content

Commit

Permalink
Fix maxBufferedResponses channel size to avoid deadlock
Browse files Browse the repository at this point in the history
Fixes #7977

Signed-off-by: Remi Vichery <[email protected]>
  • Loading branch information
rvichery committed Dec 10, 2024
1 parent b3645c8 commit 4a20358
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 1 deletion.
5 changes: 4 additions & 1 deletion pkg/receive/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -765,7 +765,10 @@ func (h *Handler) fanoutForward(ctx context.Context, params remoteWriteParams) (

// Prepare a buffered channel to receive the responses from the local and remote writes. Remote writes will all go
// asynchronously and with this capacity we will never block on writing to the channel.
maxBufferedResponses := len(localWrites)
var maxBufferedResponses int
for er := range localWrites {
maxBufferedResponses += len(localWrites[er])
}
for er := range remoteWrites {
maxBufferedResponses += len(remoteWrites[er])
}
Expand Down
51 changes: 51 additions & 0 deletions pkg/receive/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1820,6 +1820,57 @@ func TestDistributeSeries(t *testing.T) {
require.Equal(t, map[string]struct{}{"bar": {}, "boo": {}}, hr.seenTenants)
}

func TestHandlerSplitTenantLabelLocalWrite(t *testing.T) {
const tenantIDLabelName = "thanos_tenant_id"

appendable := &fakeAppendable{
appender: newFakeAppender(nil, nil, nil),
}

h := NewHandler(nil, &Options{
Endpoint: "localhost",
SplitTenantLabelName: tenantIDLabelName,
ReceiverMode: RouterIngestor,
ReplicationFactor: 1,
ForwardTimeout: 1 * time.Second,
Writer: NewWriter(
log.NewNopLogger(),
newFakeTenantAppendable(appendable),
&WriterOptions{},
),
})

// initialize hashring with a single local endpoint matching the handler endpoint to force
// using local write
hashring, err := newSimpleHashring([]Endpoint{
{
Address: h.options.Endpoint,
},
})
require.NoError(t, err)
hr := &hashringSeenTenants{Hashring: hashring}
h.Hashring(hr)

response, err := h.RemoteWrite(context.Background(), &storepb.WriteRequest{
Timeseries: []prompb.TimeSeries{
{
Labels: labelpb.ZLabelsFromPromLabels(
labels.FromStrings("a", "b", tenantIDLabelName, "bar"),
),
},
{
Labels: labelpb.ZLabelsFromPromLabels(
labels.FromStrings("b", "a", tenantIDLabelName, "foo"),
),
},
},
})

require.NoError(t, err)
require.NotNil(t, response)
require.Equal(t, map[string]struct{}{"bar": {}, "foo": {}}, hr.seenTenants)
}

func TestHandlerFlippingHashrings(t *testing.T) {
t.Parallel()

Expand Down

0 comments on commit 4a20358

Please sign in to comment.