You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pulsar.apache.org by mm...@apache.org on 2026/10/08 00:23:17 UTC
(pulsar) branch master updated: [fix][broker] Never share a segment between members of a checkpoint consumer group (#26836)
This is an automated email from the ASF dual-hosted git repository.
merlimat pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pulsar.git
The following commit(s) were added to refs/heads/master by this push:
new 813c512ddaf3 [fix][broker] Never share a segment between members of a checkpoint consumer group (#26836)
813c512ddaf3 is described below
commit 813c512ddaf3da61cab622bc27dc049723514013
Author: Matteo Merli <mm...@apache.org>
AuthorDate: Wed Oct 7 17:23:10 2026 -0700
[fix][broker] Never share a segment between members of a checkpoint consumer group (#26836)
---
.../scalable/ScalableTopicControllerTest.java | 26 ++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/pulsar-broker/src/test/java/org/apache/pulsar/broker/service/scalable/ScalableTopicControllerTest.java b/pulsar-broker/src/test/java/org/apache/pulsar/broker/service/scalable/ScalableTopicControllerTest.java
index 8fd94517428a..028894e03d27 100644
--- a/pulsar-broker/src/test/java/org/apache/pulsar/broker/service/scalable/ScalableTopicControllerTest.java
+++ b/pulsar-broker/src/test/java/org/apache/pulsar/broker/service/scalable/ScalableTopicControllerTest.java
@@ -333,6 +333,32 @@ public class ScalableTopicControllerTest {
assertEquals(resources.listConsumersAsync(topicName, "sub-a").get().size(), 1);
}
+ @Test
+ public void testRestoredCheckpointGroupGetsWholeSegments() throws Exception {
+ // One segment with N = 4 entry-buckets and three persisted members of a checkpoint group.
+ // After a controller failover the members are restored without their consumer type, which
+ // isn't persisted: the first one to reconnect must still get the segment whole.
+ TopicName oneSegment = TopicName.get("topic://tenant/ns/one-segment");
+ resources.createScalableTopicAsync(oneSegment,
+ ScalableTopicController.createInitialMetadata(1, 4, Map.of())).get();
+ resources.createSubscriptionAsync(oneSegment, "group", SubscriptionType.STREAM).get();
+ for (String member : List.of("member-1", "member-2", "member-3")) {
+ resources.registerConsumerAsync(oneSegment, "group", member).get();
+ }
+ ScalableTopicController restored = newController(oneSegment);
+ try {
+ restored.initialize().get();
+ ConsumerAssignment assignment = restored.registerConsumer("group", "member-1", 1L,
+ ScalableConsumerType.CHECKPOINT, mock(TransportCnx.class)).get();
+
+ assertEquals(assignment.assignedSegments().size(), 1);
+ assertTrue(assignment.assignedSegments().get(0).bucketRanges().isEmpty(),
+ "a checkpoint member must get the segment whole, not a share of its buckets");
+ } finally {
+ restored.close().join();
+ }
+ }
+
@Test
public void testUnregisterConsumerDeletesPersistedEntry() throws Exception {
controller.initialize().get();