22import logging
33import re
44import sys
5+ from typing import Iterable , Optional , Pattern
56import traceback
67import warnings
78
89from kafka .coordinator .assignors .roundrobin import RoundRobinPartitionAssignor
910
10- from aiokafka .abc import ConsumerRebalanceListener
11+ from aiokafka .abc import RebalanceListenerCT
1112from aiokafka .client import AIOKafkaClient
1213from aiokafka .errors import (
1314 TopicAuthorizationFailedError , OffsetOutOfRangeError ,
@@ -133,6 +134,27 @@ class AIOKafkaConsumer:
133134 group member. If API methods block waiting for messages, that time
134135 does not count against this timeout. See `KIP-62`_ for more
135136 information. Default 300000
137+ listener (RebalanceListenerCT): Optionally include listener
138+ callback, which will be called before and after each rebalance
139+ operation.
140+ As part of group management, the consumer will keep track of
141+ the list of consumers that belong to a particular group and
142+ will trigger a rebalance operation if one of the following
143+ events trigger:
144+
145+ * Number of partitions change for any of the subscribed topics
146+ * Topic is created or deleted
147+ * An existing member of the consumer group dies
148+ * A new member is added to the consumer group
149+
150+ When any of these events are triggered, the provided listener
151+ will be invoked first to indicate that the consumer's
152+ assignment has been revoked, and then again when the new
153+ assignment has been received. Note that this listener will
154+ immediately override any listener set in a previous call
155+ to subscribe. It is guaranteed, however, that the partitions
156+ revoked/assigned
157+ through this interface are from topics subscribed in this call.
136158 rebalance_timeout_ms (int): The maximum time server will wait for this
137159 consumer to rejoin the group in a case of rebalance. In Java client
138160 this behaviour is bound to `max.poll.interval.ms` configuration,
@@ -242,6 +264,7 @@ def __init__(self, *topics, loop=None,
242264 metadata_max_age_ms = 5 * 60 * 1000 ,
243265 partition_assignment_strategy = (RoundRobinPartitionAssignor ,),
244266 max_poll_interval_ms = 300000 ,
267+ listener : Optional [RebalanceListenerCT ] = None ,
245268 rebalance_timeout_ms = None ,
246269 session_timeout_ms = 10000 ,
247270 heartbeat_interval_ms = 3000 ,
@@ -324,7 +347,7 @@ def __init__(self, *topics, loop=None,
324347 if topics :
325348 topics = self ._validate_topics (topics )
326349 self ._client .set_topics (topics )
327- self ._subscription .subscribe (topics = topics )
350+ self ._subscription .subscribe (topics = topics , listener = listener )
328351
329352 def __del__ (self , _warnings = warnings ):
330353 if self ._closed is False :
@@ -1008,7 +1031,12 @@ async def end_offsets(self, partitions):
10081031 partitions , self ._request_timeout_ms )
10091032 return offsets
10101033
1011- def subscribe (self , topics = (), pattern = None , listener = None ):
1034+ def subscribe (
1035+ self ,
1036+ topics : Iterable [str ] = (),
1037+ pattern : Optional [Pattern ] = None ,
1038+ listener : Optional [RebalanceListenerCT ] = None
1039+ ) -> None :
10121040 """ Subscribe to a list of topics, or a topic regex pattern.
10131041
10141042 Partitions will be dynamically assigned via a group coordinator.
@@ -1021,7 +1049,7 @@ def subscribe(self, topics=(), pattern=None, listener=None):
10211049 topics (list): List of topics for subscription.
10221050 pattern (str): Pattern to match available topics. You must provide
10231051 either topics or pattern, but not both.
1024- listener (ConsumerRebalanceListener ): Optionally include listener
1052+ listener (RebalanceListenerCT ): Optionally include listener
10251053 callback, which will be called before and after each rebalance
10261054 operation.
10271055 As part of group management, the consumer will keep track of
@@ -1046,18 +1074,14 @@ def subscribe(self, topics=(), pattern=None, listener=None):
10461074 IllegalStateError: if called after previously calling :meth:`assign`
10471075 ValueError: if neither topics or pattern is provided or both
10481076 are provided
1049- TypeError: if listener is not a :class:`.ConsumerRebalanceListener`
10501077 """
10511078 if not (topics or pattern ):
10521079 raise ValueError (
10531080 "You should provide either `topics` or `pattern`" )
10541081 if topics and pattern :
10551082 raise ValueError (
10561083 "You can't provide both `topics` and `pattern`" )
1057- if listener is not None and \
1058- not isinstance (listener , ConsumerRebalanceListener ):
1059- raise TypeError (
1060- "listener should be an instance of ConsumerRebalanceListener" )
1084+
10611085 if pattern is not None :
10621086 try :
10631087 pattern = re .compile (pattern )
0 commit comments