Skip to content

Commit b0b7805

Browse files
committed
Add ConsumerSeekAware Example
1 parent 84efda3 commit b0b7805

File tree

1 file changed

+69
-0
lines changed

1 file changed

+69
-0
lines changed

src/reference/asciidoc/kafka.adoc

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1855,6 +1855,75 @@ See <<idle-containers>> for how to enable idle container detection.
18551855

18561856
To arbitrarily seek at runtime, use the callback reference from the `registerSeekCallback` for the appropriate thread.
18571857

1858+
Here is a trivial Spring Boot application that demonstrates how to use the callback; it sends 10 records to the topic; hitting `<Enter>` in the console causes all partitions to seek to the beginning.
1859+
1860+
====
1861+
[source, java]
1862+
----
1863+
@SpringBootApplication
1864+
public class SeekExampleApplication {
1865+
1866+
public static void main(String[] args) {
1867+
SpringApplication.run(SeekExampleApplication.class, args);
1868+
}
1869+
1870+
@Bean
1871+
public ApplicationRunner runner(Listener listener, KafkaTemplate<String, String> template) {
1872+
return args -> {
1873+
IntStream.range(0, 10).forEach(i -> template.send(
1874+
new ProducerRecord<>("seekExample", i % 3, "foo", "bar")));
1875+
while (true) {
1876+
System.in.read();
1877+
listener.seekToStart();
1878+
}
1879+
};
1880+
}
1881+
1882+
@Bean
1883+
public NewTopic topic() {
1884+
return new NewTopic("seekExample", 3, (short) 1);
1885+
}
1886+
1887+
}
1888+
1889+
@Component
1890+
class Listener implements ConsumerSeekAware {
1891+
1892+
1893+
private static final Logger logger = LoggerFactory.getLogger(Listener.class);
1894+
1895+
1896+
private final Map<TopicPartition, ConsumerSeekCallback> callbacks = new ConcurrentHashMap<>();
1897+
1898+
private static final ThreadLocal<ConsumerSeekCallback> callbackForThread = new ThreadLocal<>();
1899+
1900+
@Override
1901+
public void registerSeekCallback(ConsumerSeekCallback callback) {
1902+
callbackForThread.set(callback);
1903+
}
1904+
1905+
@Override
1906+
public void onPartitionsAssigned(Map<TopicPartition, Long> assignments, ConsumerSeekCallback callback) {
1907+
assignments.keySet().forEach(tp -> this.callbacks.put(tp, callbackForThread.get()));
1908+
}
1909+
1910+
@Override
1911+
public void onIdleContainer(Map<TopicPartition, Long> assignments, ConsumerSeekCallback callback) {
1912+
}
1913+
1914+
@KafkaListener(id = "seekExample", topics = "seekExample", concurrency = "3")
1915+
public void listen(ConsumerRecord<String, String> in) {
1916+
logger.info(in.toString());
1917+
}
1918+
1919+
public void seekToStart() {
1920+
this.callbacks.forEach((tp, callback) -> callback.seekToBeginning(tp.topic(), tp.partition()));
1921+
}
1922+
1923+
}
1924+
----
1925+
====
1926+
18581927
[[container-factory]]
18591928
===== Container factory
18601929

0 commit comments

Comments
 (0)