use of org.zalando.nakadi.exceptions.runtime.RebalanceConflictException in project nakadi by zalando.
the class SubscriptionRebalancer method apply.
@Override
public Partition[] apply(final Collection<Session> sessions, final Partition[] currentPartitions) {
final List<String> activeSessions = sessions.stream().map(Session::getId).collect(Collectors.toList());
final List<Partition> partitionsLeft = Lists.newArrayList(currentPartitions);
final List<Partition> changedPartitions = new ArrayList<>();
final List<Session> sessionsWithSpecifiedPartitions = sessions.stream().filter(s -> !s.getRequestedPartitions().isEmpty()).collect(Collectors.toList());
// go through all sessions that directly requested partitions to stream
for (final Session session : sessionsWithSpecifiedPartitions) {
for (final EventTypePartition requestedPartition : session.getRequestedPartitions()) {
// find a partition that is requested and assign it to a session that requests it
final Partition partition = partitionsLeft.stream().filter(p -> p.getKey().equals(requestedPartition)).findFirst().orElseThrow(() -> new RebalanceConflictException("Two existing sessions request the same partition: " + requestedPartition));
partitionsLeft.remove(partition);
// if this partition is not assigned to this session - move it
if (!session.getId().equals(partition.getSession())) {
final Partition movedPartition = partition.moveToSessionId(session.getId(), activeSessions);
changedPartitions.add(movedPartition);
}
}
}
// for the rest of partitions/sessions perform a rebalance based on partitions count
final List<Session> autoBalanceSessions = sessions.stream().filter(s -> s.getRequestedPartitions().isEmpty()).collect(Collectors.toList());
if (!autoBalanceSessions.isEmpty() && !partitionsLeft.isEmpty()) {
final Partition[] partitionsChangedByAutoRebalance = rebalanceByWeight(autoBalanceSessions, partitionsLeft.toArray(new Partition[partitionsLeft.size()]));
changedPartitions.addAll(Arrays.asList(partitionsChangedByAutoRebalance));
}
return changedPartitions.toArray(new Partition[changedPartitions.size()]);
}
Aggregations