This is an automated email from the ASF dual-hosted git repository.
nizhikov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite-extensions.git
The following commit(s) were added to refs/heads/master by this push:
new da1a874c IGNITE-19369 Update metadata topic offset only after commit
(#212)
da1a874c is described below
commit da1a874c27b93923f07d9c0a6876dcca1146a9c2
Author: Nikolay <[email protected]>
AuthorDate: Wed Apr 26 15:56:43 2023 +0300
IGNITE-19369 Update metadata topic offset only after commit (#212)
---
.../ignite/cdc/kafka/IgniteToKafkaCdcStreamer.java | 4 +-
.../cdc/kafka/KafkaToIgniteMetadataUpdater.java | 44 +++++++++++++++++++---
2 files changed, 40 insertions(+), 8 deletions(-)
diff --git
a/modules/cdc-ext/src/main/java/org/apache/ignite/cdc/kafka/IgniteToKafkaCdcStreamer.java
b/modules/cdc-ext/src/main/java/org/apache/ignite/cdc/kafka/IgniteToKafkaCdcStreamer.java
index a7117480..0dce9442 100644
---
a/modules/cdc-ext/src/main/java/org/apache/ignite/cdc/kafka/IgniteToKafkaCdcStreamer.java
+++
b/modules/cdc-ext/src/main/java/org/apache/ignite/cdc/kafka/IgniteToKafkaCdcStreamer.java
@@ -201,7 +201,7 @@ public class IgniteToKafkaCdcStreamer implements
CdcConsumer {
@Override public void onTypes(Iterator<BinaryType> types) {
sendAll(
types,
- t -> new ProducerRecord<>(metadataTopic,
IgniteUtils.toBytes(((BinaryTypeImpl)t).metadata())),
+ t -> new ProducerRecord<>(metadataTopic, 0, null,
IgniteUtils.toBytes(((BinaryTypeImpl)t).metadata())),
typesCnt
);
@@ -212,7 +212,7 @@ public class IgniteToKafkaCdcStreamer implements
CdcConsumer {
@Override public void onMappings(Iterator<TypeMapping> mappings) {
sendAll(
mappings,
- m -> new ProducerRecord<>(metadataTopic, IgniteUtils.toBytes(m)),
+ m -> new ProducerRecord<>(metadataTopic, 0, null,
IgniteUtils.toBytes(m)),
mappingsCnt
);
diff --git
a/modules/cdc-ext/src/main/java/org/apache/ignite/cdc/kafka/KafkaToIgniteMetadataUpdater.java
b/modules/cdc-ext/src/main/java/org/apache/ignite/cdc/kafka/KafkaToIgniteMetadataUpdater.java
index 15e793aa..b8e8a9ad 100644
---
a/modules/cdc-ext/src/main/java/org/apache/ignite/cdc/kafka/KafkaToIgniteMetadataUpdater.java
+++
b/modules/cdc-ext/src/main/java/org/apache/ignite/cdc/kafka/KafkaToIgniteMetadataUpdater.java
@@ -25,6 +25,7 @@ import java.util.Properties;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;
+import org.apache.ignite.IgniteException;
import org.apache.ignite.IgniteLogger;
import org.apache.ignite.cdc.TypeMapping;
import org.apache.ignite.internal.binary.BinaryContext;
@@ -35,6 +36,8 @@ import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
+import org.apache.kafka.clients.consumer.OffsetAndMetadata;
+import org.apache.kafka.clients.consumer.OffsetCommitCallback;
import org.apache.kafka.common.TopicPartition;
import org.apache.kafka.common.serialization.ByteArrayDeserializer;
import org.apache.kafka.common.serialization.VoidDeserializer;
@@ -46,7 +49,7 @@ import static
org.apache.kafka.clients.consumer.ConsumerConfig.KEY_DESERIALIZER_
import static
org.apache.kafka.clients.consumer.ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG;
/** */
-public class KafkaToIgniteMetadataUpdater implements AutoCloseable {
+public class KafkaToIgniteMetadataUpdater implements AutoCloseable,
OffsetCommitCallback {
/** Binary context. */
private final BinaryContext ctx;
@@ -63,7 +66,10 @@ public class KafkaToIgniteMetadataUpdater implements
AutoCloseable {
private final AtomicLong rcvdEvts = new AtomicLong();
/** Offsets from the last successful metadata update. */
- private Map<TopicPartition, Long> offsets;
+ private volatile Map<TopicPartition, Long> offsets;
+
+ /** Possible commit error. */
+ private volatile Exception err;
/** Metadata topic partitions. */
private final Set<TopicPartition> parts;
@@ -112,6 +118,9 @@ public class KafkaToIgniteMetadataUpdater implements
AutoCloseable {
/** Polls all available records from metadata topic and applies it to
Ignite. */
public synchronized void updateMetadata() {
+ if (err != null)
+ throw new IgniteException(err);
+
// If there are no new records in topic, method KafkaConsumer#poll
blocks up to the specified timeout.
// In order to eliminate this, we compare current offsets with the
offsets from the last metadata update
// (stored in 'offsets' field). If there are no offsets changes,
polling cycle is skipped.
@@ -124,13 +133,15 @@ public class KafkaToIgniteMetadataUpdater implements
AutoCloseable {
return;
}
- offsets = new HashMap<>(offsets0);
-
while (true) {
ConsumerRecords<Void, byte[]> recs =
cnsmr.poll(Duration.ofMillis(kafkaReqTimeout));
- if (recs.count() == 0)
+ if (recs.count() == 0) {
+ if (log.isDebugEnabled())
+ log.debug("Empty poll from meta topic");
+
return;
+ }
if (log.isInfoEnabled())
log.info("Polled from meta topic [rcvdEvts=" +
rcvdEvts.addAndGet(recs.count()) + ']');
@@ -146,8 +157,29 @@ public class KafkaToIgniteMetadataUpdater implements
AutoCloseable {
throw new IllegalArgumentException("Unknown meta
type[type=" + data + ']');
}
- cnsmr.commitSync(Duration.ofMillis(kafkaReqTimeout));
+ // Offsets updated only after commit.
+ cnsmr.commitAsync(this);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public void onComplete(Map<TopicPartition, OffsetAndMetadata>
committed, Exception err) {
+ if (err != null) {
+ log.warning("Commit error:", err);
+
+ this.err = err;
+
+ return;
}
+
+ Map<TopicPartition, Long> offsets0 = new HashMap<>();
+
+ committed.forEach((tp, offAndMeta) -> offsets0.put(tp,
offAndMeta.offset()));
+
+ if (log.isDebugEnabled())
+ log.debug("Offset committed: " + offsets0);
+
+ offsets = offsets0;
}
/** {@inheritDoc} */