def drain_by_nodes(self, ignore_nodes): """return batches by nodes""" nodes = collections.defaultdict(dict) unknown_leaders_exist = False for tp in list(self._batches.keys()): leader = self._cluster.leader_for_partition(tp) if leader is None or leader == -1: if self._batches[tp].expired(): # batch is for partition is expired and still no leader, # so set exception for batch and pop it batch = self._pop_batch(tp) if leader is None: err = NotLeaderForPartitionError() else: err = LeaderNotAvailableError() batch.done(exception=err) unknown_leaders_exist = True continue elif ignore_nodes and leader in ignore_nodes: continue batch = self._pop_batch(tp) nodes[leader][tp] = batch # all batches are drained from accumulator # so create "wait data" future again for waiting new data in send # task if not self._wait_data_future.done(): self._wait_data_future.set_result(None) self._wait_data_future = asyncio.Future(loop=self._loop) return nodes, unknown_leaders_exist
def _get_leader_for_partition(self, topic, partition): """ Returns the leader for a partition or None if the partition exists but has no leader. UnknownTopicOrPartitionError will be raised if the topic or partition is not part of the metadata. LeaderNotAvailableError is raised if server has metadata, but there is no current leader """ key = TopicAndPartition(topic, partition) # Use cached metadata if it is there if self.topics_to_brokers.get(key) is not None: return self.topics_to_brokers[key] # Otherwise refresh metadata # If topic does not already exist, this will raise # UnknownTopicOrPartitionError if not auto-creating # LeaderNotAvailableError otherwise until partitions are created self.load_metadata_for_topics(topic) # If the partition doesn't actually exist, raise if partition not in self.topic_partitions[topic]: raise UnknownTopicOrPartitionError(key) # If there's no leader for the partition, raise meta = self.topic_partitions[topic][partition] if meta.leader == -1: raise LeaderNotAvailableError(meta) # Otherwise return the BrokerMetadata return self.brokers[meta.leader]