Skip to content

Commit 5c73e96

Browse files
nikita-kibitkinspring-builds
authored andcommitted
GH-4444: Consider ackTime for COUNT_TIME commits (#4449)
Fixes #4444 Signed-off-by: Nikita Kibitkin <nikita.n.kibitkin@gmail.com> (cherry picked from commit 1de4584)
1 parent 4a75e85 commit 5c73e96

2 files changed

Lines changed: 57 additions & 2 deletions

File tree

spring-kafka/src/main/java/org/springframework/kafka/listener/KafkaMessageListenerContainer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3188,10 +3188,10 @@ private void processCommits() {
31883188
if (this.isCountAck) {
31893189
countAcks();
31903190
}
3191-
else if (this.isTimeAck) {
3191+
if (this.isTimeAck) {
31923192
timedAcks();
31933193
}
3194-
else if (!this.isManualImmediateAck) {
3194+
if (!this.isCountAck && !this.isTimeAck && !this.isManualImmediateAck) {
31953195
commitIfNecessary();
31963196
this.count = 0;
31973197
}

spring-kafka/src/test/java/org/springframework/kafka/listener/KafkaMessageListenerContainerTests.java

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3350,6 +3350,61 @@ public void testAckModeCount() throws Exception {
33503350
container.stop();
33513351
}
33523352

3353+
@SuppressWarnings({ "unchecked", "rawtypes" })
3354+
@Test
3355+
public void testAckModeCountTimeCommitsWhenTimeElapsed() throws Exception {
3356+
ConsumerFactory<Integer, String> cf = mock(ConsumerFactory.class);
3357+
Consumer<Integer, String> consumer = mock(Consumer.class);
3358+
given(cf.createConsumer(eq("grp"), eq("clientId"), isNull(), any())).willReturn(consumer);
3359+
Map<String, Object> cfProps = new HashMap<>();
3360+
cfProps.put(ConsumerConfig.DEFAULT_API_TIMEOUT_MS_CONFIG, 45000);
3361+
given(cf.getConfigurationProperties()).willReturn(cfProps);
3362+
TopicPartition topicPartition = new TopicPartition("foo", 0);
3363+
final Map<TopicPartition, List<ConsumerRecord<Integer, String>>> records = new HashMap<>();
3364+
records.put(topicPartition, Collections.singletonList(
3365+
new ConsumerRecord<>("foo", 0, 0L, 1, "foo")));
3366+
ConsumerRecords<Integer, String> consumerRecords = new ConsumerRecords<>(records, Map.of());
3367+
given(consumer.poll(any(Duration.class))).willAnswer(i -> {
3368+
Thread.sleep(50);
3369+
return consumerRecords;
3370+
});
3371+
final CountDownLatch commitLatch = new CountDownLatch(1);
3372+
willAnswer(i -> {
3373+
commitLatch.countDown();
3374+
return null;
3375+
}).given(consumer).commitSync(anyMap(), eq(Duration.ofSeconds(42)));
3376+
given(consumer.assignment()).willReturn(records.keySet());
3377+
TopicPartitionOffset[] topicPartitionOffset = new TopicPartitionOffset[] {
3378+
new TopicPartitionOffset("foo", 0) };
3379+
ContainerProperties containerProps = new ContainerProperties(topicPartitionOffset);
3380+
containerProps.setGroupId("grp");
3381+
containerProps.setAckMode(AckMode.COUNT_TIME);
3382+
containerProps.setAckCount(Integer.MAX_VALUE);
3383+
containerProps.setAckTime(10);
3384+
containerProps.setClientId("clientId");
3385+
containerProps.setMissingTopicsFatal(false);
3386+
AtomicInteger recordCount = new AtomicInteger();
3387+
containerProps.setMessageListener((MessageListener) r -> {
3388+
recordCount.incrementAndGet();
3389+
});
3390+
Properties consumerProps = new Properties();
3391+
consumerProps.setProperty(ConsumerConfig.DEFAULT_API_TIMEOUT_MS_CONFIG, "42000"); // wins
3392+
containerProps.setKafkaConsumerProperties(consumerProps);
3393+
containerProps.setMissingTopicsFatal(false);
3394+
KafkaMessageListenerContainer<Integer, String> container =
3395+
new KafkaMessageListenerContainer<>(cf, containerProps);
3396+
try {
3397+
container.start();
3398+
assertThat(commitLatch.await(10, TimeUnit.SECONDS)).isTrue();
3399+
assertThat(recordCount.get()).isGreaterThan(0);
3400+
verify(consumer).commitSync(Collections.singletonMap(topicPartition, new OffsetAndMetadata(1L)),
3401+
Duration.ofSeconds(42));
3402+
}
3403+
finally {
3404+
container.stop();
3405+
}
3406+
}
3407+
33533408
@SuppressWarnings({ "unchecked", "rawtypes"})
33543409
@Test
33553410
public void testCommitErrorHandlerCalled() throws Exception {

0 commit comments

Comments
 (0)