Search in sources :

Example 1 with RebalanceConflictException

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()]);
}
Also used : IntStream(java.util.stream.IntStream) Arrays(java.util.Arrays) EventTypePartition(org.zalando.nakadi.domain.EventTypePartition) Session(org.zalando.nakadi.service.subscription.model.Session) Collection(java.util.Collection) BiFunction(java.util.function.BiFunction) Collectors(java.util.stream.Collectors) ArrayList(java.util.ArrayList) Partition(org.zalando.nakadi.service.subscription.model.Partition) RebalanceConflictException(org.zalando.nakadi.exceptions.runtime.RebalanceConflictException) List(java.util.List) Lists(com.google.common.collect.Lists) Stream(java.util.stream.Stream) Map(java.util.Map) EventTypePartition(org.zalando.nakadi.domain.EventTypePartition) Partition(org.zalando.nakadi.service.subscription.model.Partition) RebalanceConflictException(org.zalando.nakadi.exceptions.runtime.RebalanceConflictException) ArrayList(java.util.ArrayList) EventTypePartition(org.zalando.nakadi.domain.EventTypePartition) Session(org.zalando.nakadi.service.subscription.model.Session)

Aggregations

Lists (com.google.common.collect.Lists)1 ArrayList (java.util.ArrayList)1 Arrays (java.util.Arrays)1 Collection (java.util.Collection)1 List (java.util.List)1 Map (java.util.Map)1 BiFunction (java.util.function.BiFunction)1 Collectors (java.util.stream.Collectors)1 IntStream (java.util.stream.IntStream)1 Stream (java.util.stream.Stream)1 EventTypePartition (org.zalando.nakadi.domain.EventTypePartition)1 RebalanceConflictException (org.zalando.nakadi.exceptions.runtime.RebalanceConflictException)1 Partition (org.zalando.nakadi.service.subscription.model.Partition)1 Session (org.zalando.nakadi.service.subscription.model.Session)1