-
Notifications
You must be signed in to change notification settings - Fork 137
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixes regression issue with order of state truncation vs commit (#362)
It's important that the commit happens before state truncation. This regressed with the merge of the Batching system, it's unknown why. There is now test coverage for the specific behaviour. The effect should be zero duplicates upon healthy rebalancing.
- Loading branch information
Showing
8 changed files
with
142 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23 changes: 7 additions & 16 deletions
23
...sumer-core/src/main/java/io/confluent/parallelconsumer/internal/InternalRuntimeError.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,14 @@ | ||
package io.confluent.parallelconsumer.internal; | ||
|
||
/*- | ||
* Copyright (C) 2020-2021 Confluent, Inc. | ||
* Copyright (C) 2020-2022 Confluent, Inc. | ||
*/ | ||
public class InternalRuntimeError extends RuntimeException { | ||
|
||
public InternalRuntimeError(final String message) { | ||
super(message); | ||
} | ||
|
||
public InternalRuntimeError(final String message, final Throwable cause) { | ||
super(message, cause); | ||
} | ||
|
||
public InternalRuntimeError(final Throwable cause) { | ||
super(cause); | ||
} | ||
import lombok.experimental.StandardException; | ||
|
||
public InternalRuntimeError(final String message, final Throwable cause, final boolean enableSuppression, final boolean writableStackTrace) { | ||
super(message, cause, enableSuppression, writableStackTrace); | ||
} | ||
/** | ||
* Generic internal runtime error | ||
*/ | ||
@StandardException | ||
public class InternalRuntimeError extends RuntimeException { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
88 changes: 88 additions & 0 deletions
88
...c/test-integration/java/io/confluent/parallelconsumer/integrationTests/RebalanceTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
package io.confluent.parallelconsumer.integrationTests; | ||
|
||
/*- | ||
* Copyright (C) 2020-2022 Confluent, Inc. | ||
*/ | ||
|
||
import io.confluent.parallelconsumer.ParallelConsumerOptions; | ||
import io.confluent.parallelconsumer.ParallelEoSStreamProcessor; | ||
import io.confluent.parallelconsumer.integrationTests.utils.KafkaClientUtils; | ||
import lombok.SneakyThrows; | ||
import org.apache.kafka.clients.consumer.Consumer; | ||
import org.apache.kafka.clients.consumer.ConsumerRecords; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.Test; | ||
import pl.tlinkowski.unij.api.UniLists; | ||
import pl.tlinkowski.unij.api.UniSets; | ||
|
||
import java.time.Duration; | ||
import java.util.concurrent.atomic.AtomicLong; | ||
|
||
import static io.confluent.parallelconsumer.ManagedTruth.assertThat; | ||
import static io.confluent.parallelconsumer.ParallelConsumerOptions.ProcessingOrder.PARTITION; | ||
import static io.confluent.parallelconsumer.integrationTests.utils.KafkaClientUtils.GroupOption.RESUE_GROUP; | ||
import static org.testcontainers.shaded.org.awaitility.Awaitility.await; | ||
import static org.testcontainers.shaded.org.hamcrest.Matchers.equalTo; | ||
import static org.testcontainers.shaded.org.hamcrest.Matchers.is; | ||
|
||
/** | ||
* Tests around what should happen when rebalancing occurs | ||
* | ||
* @author Antony Stubbs | ||
*/ | ||
class RebalanceTest extends BrokerIntegrationTest<String, String> { | ||
|
||
Consumer<String, String> consumer; | ||
|
||
ParallelEoSStreamProcessor<String, String> pc; | ||
|
||
public static final Duration INFINITE = Duration.ofDays(1); | ||
|
||
{ | ||
super.numPartitions = 2; | ||
} | ||
|
||
// todo refactor move up | ||
@BeforeEach | ||
void setup() { | ||
setupTopic(); | ||
consumer = getKcu().createNewConsumer(KafkaClientUtils.GroupOption.NEW_GROUP); | ||
|
||
pc = new ParallelEoSStreamProcessor<>(ParallelConsumerOptions.<String, String>builder() | ||
.consumer(consumer) | ||
.ordering(PARTITION) // just so we dont need to use keys | ||
.build()); | ||
|
||
pc.subscribe(UniSets.of(topic)); | ||
} | ||
|
||
/** | ||
* Checks that when a rebalance happens, a final commit is done first for revoked partitions (that will be assigned | ||
* to new consumers), so that the new consumer doesn't reprocess records that are already complete. | ||
*/ | ||
@SneakyThrows | ||
@Test | ||
void commitUponRevoke() { | ||
var recordsCount = 20L; | ||
var count = new AtomicLong(); | ||
|
||
// | ||
kcu.produceMessages(topic, recordsCount); | ||
|
||
// effectively disable commit | ||
pc.setTimeBetweenCommits(INFINITE); | ||
|
||
// consume all the messages | ||
pc.poll(recordContexts -> count.getAndIncrement()); | ||
await().untilAtomic(count, is(equalTo(recordsCount))); | ||
|
||
// cause rebalance | ||
var newConsumer = kcu.createNewConsumer(RESUE_GROUP); | ||
newConsumer.subscribe(UniLists.of(topic)); | ||
ConsumerRecords<Object, Object> poll = newConsumer.poll(Duration.ofSeconds(5)); | ||
|
||
// make sure only there are no duplicates | ||
assertThat(poll).hasCountEqualTo(0); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters