def drain_by_nodes(self, ignore_nodes): """ Group batches by leader to partiton 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][0].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 = create_future(loop=self._loop) return nodes, unknown_leaders_exist
def drain_by_nodes(self, ignore_nodes, muted_partitions=set()): """ Group batches by leader to partiton nodes. """ nodes = collections.defaultdict(dict) unknown_leaders_exist = False for tp in list(self._batches.keys()): # Just ignoring by node is not enough, as leader can change during # the cycle if tp in muted_partitions: continue leader = self._cluster.leader_for_partition(tp) if leader is None or leader == -1: if self._batches[tp][0].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.failure(exception=err) unknown_leaders_exist = True continue elif ignore_nodes and leader in ignore_nodes: continue batch = self._pop_batch(tp) # We can get an empty batch here if all `append()` calls failed # with validation... if not batch.is_empty(): nodes[leader][tp] = batch else: # XXX: use something more graceful. We just want to trigger # delivery future here, no message futures. batch.done_noack() # 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 = create_future(loop=self._loop) return nodes, unknown_leaders_exist