spring-cloud / spring-cloud/spring-cloud-stream
Provide an extension point for setting offsets before starting container
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 1.1k
- Forks
- 646
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 8
Description
@dsyer commented on Mon Sep 09 2019
Currently there seems to be no way to expose the equivalent of this using Spring Cloud Stream:
@KafkaListener(topicPartitions = { @TopicPartition(partitionOffsets = {
@PartitionOffset(partition = "#{config.partition}", initialOffset = "#{config.offset}") }, topic = "#{config.topic}") })
public void consumer(Message<?> message) {
...
}
The only flexibility with offsets in Spring Cloud Stream is to set the consumer to seek to "BEGINNING" or "END" (nothing that corresponds to an actual long offset).
This will be essential for providing the "effectively once" semantics for quality of service (storing offsets outside Kafka).
@garyrussell commented on Mon Sep 09 2019
Add a ListenerContainerCustomizer. container.getContainerProperties().setConsumerRebalanceListener(...).
Use a ConsumerAwareRebalanceListener and consumer.seek(...)s.
Sent from 'phone... apologies for lack of verbosity and formatting.
@garyrussell commented on Mon Sep 09 2019
Oh. That will only work with group management. Your question uses manual partition assignment. There is no hook for setting offsets in that mode.
@dsyer commented on Tue Sep 10 2019
Actually it does seem to work - I don't need manual partition assignment; it was just the only way to make @KafkaListener accept an initial offset. Here's what I have:
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) throws Exception {
new SpringApplicationBuilder(DemoApplication.class).run(args);
}
@Bean
public Consumer<Message<?>> consumer() {
return message -> {
System.err.println(message);
};
}
@Bean
public ListenerContainerCustomizer<AbstractMessageListenerContainer<?, ?>> listenerCustomizer() {
return new ListenerContainerCustomizer<AbstractMessageListenerContainer<?, ?>>() {
@Override
public void configure(AbstractMessageListenerContainer<?, ?> container,
String destinationName, String group) {
System.err.println("Customizing: " + group);
container.getContainerProperties().setConsumerRebalanceListener(
new ConsumerAwareRebalanceListener() {
@Override
public void onPartitionsAssigned(
org.apache.kafka.clients.consumer.Consumer<?, ?> consumer,
Collection<TopicPartition> partitions) {
for (TopicPartition partition : partitions) {
System.err.println("Seeking: " + partition);
consumer.seek(partition, 3);
}
}
});
}
};
}
}
I only see messages from offset 3, independent of whether I set spring.cloud.stream.bindings.input.group or not. This is perfect if it is actually working as it appears to be. We could document it a bit, I guess.
@dsyer commented on Tue Sep 10 2019
Also, if this is the only way to do it, there is another problem which is that there is only one ListenerContainerCustomizer and only one ConsumerRebalanceListener, so if I make a library with one of these, there is no room for additional customization by the user.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with ListenerContainerCustomizer, AbstractMessageListenerContainer, and ConsumerAwareRebalanceListener to understand the existing customization path and offset seeking behavior. Define how multiple customizers or rebalance listeners can coexist, then verify that a user can configure the required offset behavior without blocking library-provided customization.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, kafka, spring
- Domain
- backend, stream-processing
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100