Skip to content

Commit f8eddfc

Browse files
committed
Add a listener for rebalances.
1 parent 7b9c99d commit f8eddfc

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

reader.go

+20
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,23 @@ func (r *Reader) run(cg *ConsumerGroup) {
304304
for attempt := 1; attempt <= r.config.MaxAttempts; attempt++ {
305305
gen, err = cg.Next(r.stctx)
306306
if err == nil {
307+
if r.config.AssignmentListener != nil {
308+
assignments := make([]GroupMemberTopic, 0, len(gen.Assignments))
309+
for topic, partitions := range gen.Assignments {
310+
assignedPartitions := make([]int, 0, len(partitions))
311+
for _, partition := range partitions {
312+
assignedPartitions = append(assignedPartitions, partition.ID)
313+
}
314+
sort.Slice(assignedPartitions, func(i, j int) bool {
315+
return assignedPartitions[i] < assignedPartitions[j]
316+
})
317+
assignments = append(assignments, GroupMemberTopic{
318+
Topic: topic,
319+
Partitions: assignedPartitions,
320+
})
321+
}
322+
r.config.AssignmentListener(assignments)
323+
}
307324
break
308325
}
309326
if errors.Is(err, r.stctx.Err()) {
@@ -522,6 +539,9 @@ type ReaderConfig struct {
522539
// This flag is being added to retain backwards-compatibility, so it will be
523540
// removed in a future version of kafka-go.
524541
OffsetOutOfRangeError bool
542+
543+
// AsignmentListener is called when a reassignment happens indicating what are the new partitions
544+
AssignmentListener func(partitions []GroupMemberTopic)
525545
}
526546

527547
// Validate method validates ReaderConfig properties.

reader_test.go

+44
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"testing"
1616
"time"
1717

18+
"github.com/stretchr/testify/assert"
1819
"github.com/stretchr/testify/require"
1920
)
2021

@@ -890,6 +891,49 @@ func TestReaderConsumerGroup(t *testing.T) {
890891
}
891892
}
892893

894+
func TestAssignmentListener(t *testing.T) {
895+
// It appears that some of the tests depend on all these tests being
896+
// run concurrently to pass... this is brittle and should be fixed
897+
// at some point.
898+
t.Parallel()
899+
900+
topic := makeTopic()
901+
createTopic(t, topic, 10)
902+
defer deleteTopic(t, topic)
903+
904+
var lock sync.Mutex
905+
assignments := make([][]GroupMemberTopic, 0)
906+
groupID := makeGroupID()
907+
r := NewReader(ReaderConfig{
908+
Brokers: []string{"localhost:9092"},
909+
Topic: topic,
910+
GroupID: groupID,
911+
HeartbeatInterval: 2 * time.Second,
912+
CommitInterval: 1 * time.Second,
913+
RebalanceTimeout: 2 * time.Second,
914+
RetentionTime: time.Hour,
915+
MinBytes: 1,
916+
MaxBytes: 1e6,
917+
AssignmentListener: func(partitions []GroupMemberTopic) {
918+
lock.Lock()
919+
defer lock.Unlock()
920+
assignments = append(assignments, partitions)
921+
},
922+
})
923+
defer r.Close()
924+
925+
assert.Eventually(t, func() bool {
926+
return reflect.DeepEqual(assignments, [][]GroupMemberTopic{
927+
{
928+
GroupMemberTopic{
929+
Topic: topic,
930+
Partitions: []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
931+
},
932+
},
933+
})
934+
}, 10*time.Second, 100*time.Millisecond)
935+
}
936+
893937
func testReaderConsumerGroupHandshake(t *testing.T, ctx context.Context, r *Reader) {
894938
prepareReader(t, context.Background(), r, makeTestSequence(5)...)
895939

0 commit comments

Comments
 (0)