use of org.zalando.nakadi.service.subscription.model.Session in project nakadi by zalando.
the class SubscriptionRebalancerTest method onlyDirectSessionsWorkFine.
@Test
public void onlyDirectSessionsWorkFine() {
final Partition[] changeset = new SubscriptionRebalancer().apply(ImmutableList.of(new Session("s1", 1, ImmutableList.of(new EventTypePartition("et1", "p3"))), new Session("s2", 1, ImmutableList.of(new EventTypePartition("et1", "p2")))), new Partition[] { new Partition("et1", "p1", null, null, UNASSIGNED), new Partition("et1", "p2", null, null, UNASSIGNED), new Partition("et1", "p3", null, null, UNASSIGNED), new Partition("et1", "p4", null, null, UNASSIGNED) });
assertEquals(newHashSet(changeset), newHashSet(new Partition("et1", "p3", "s1", null, ASSIGNED), new Partition("et1", "p2", "s2", null, ASSIGNED)));
}
use of org.zalando.nakadi.service.subscription.model.Session in project nakadi by zalando.
the class ZkSubscriptionNodeTest method before.
@Before
public void before() {
final List<Partition> partitions = ImmutableList.of(new Partition("et1", "0", "stream1", null, Partition.State.ASSIGNED), new Partition("et1", "1", "stream2", "stream4", Partition.State.REASSIGNING), new Partition("et2", "0", "stream3", null, Partition.State.UNASSIGNED), new Partition("et2", "1", null, null, null));
final List<Session> sessions = ImmutableList.of(new Session("stream1", 1, ImmutableList.of(new EventTypePartition("et1", "0"))), new Session("stream2", 1), new Session("stream3", 1), new Session("stream4", 1));
zkSubscriptionNode = new ZkSubscriptionNode(partitions, sessions);
}
use of org.zalando.nakadi.service.subscription.model.Session in project nakadi by zalando.
the class AbstractZkSubscriptionClient method listSessions.
@Override
public final Collection<Session> listSessions() throws SubscriptionNotInitializedException, NakadiRuntimeException, ServiceTemporarilyUnavailableException {
getLog().info("fetching sessions information");
final List<String> zkSessions;
try {
zkSessions = getCurator().getChildren().forPath(getSubscriptionPath("/sessions"));
} catch (final KeeperException.NoNodeException e) {
throw new SubscriptionNotInitializedException(getSubscriptionId());
} catch (Exception ex) {
throw new NakadiRuntimeException(ex);
}
return loadDataAsync(zkSessions, key -> getSubscriptionPath("/sessions/" + key), this::deserializeSession).values();
}
use of org.zalando.nakadi.service.subscription.model.Session in project nakadi by zalando.
the class SubscriptionStreamerFactory method build.
public SubscriptionStreamer build(final Subscription subscription, final StreamParameters streamParameters, final SubscriptionOutput output, final AtomicBoolean connectionReady, final BlacklistService blacklistService) throws InternalNakadiException, NoSuchEventTypeException {
final Session session = Session.generate(1, streamParameters.getPartitions());
final String loggingPath = "subscription." + subscription.getId() + "." + session.getId();
// Create streaming context
return new StreamingContext.Builder().setOut(output).setStreamMemoryLimitBytes(streamMemoryLimitBytes).setParameters(streamParameters).setSession(session).setTimer(executorService).setZkClient(zkClientFactory.createClient(subscription, loggingPath)).setRebalancer(new SubscriptionRebalancer()).setKafkaPollTimeout(kafkaPollTimeout).setLoggingPath(loggingPath).setConnectionReady(connectionReady).setCursorTokenService(cursorTokenService).setObjectMapper(objectMapper).setBlacklistService(blacklistService).setCursorConverter(cursorConverter).setSubscription(subscription).setMetricRegistry(metricRegistry).setTimelineService(timelineService).setWriter(eventStreamWriterProvider.getWriter()).setAuthorizationValidator(authorizationValidator).setEventTypeChangeListener(eventTypeChangeListener).setCursorComparator(new NakadiCursorComparator(eventTypeCache)).setKpiPublisher(nakadiKpiPublisher).setKpiDataStremedEventType(kpiDataStreamedEventType).setKpiCollectionFrequencyMs(kpiCollectionFrequencyMs).build();
}
use of org.zalando.nakadi.service.subscription.model.Session 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