Search in sources :

Example 51 with NakadiCursor

use of org.zalando.nakadi.domain.NakadiCursor in project nakadi by zalando.

the class SubscriptionValidationService method validateInitialCursors.

private void validateInitialCursors(final SubscriptionBase subscription, final List<EventTypePartition> allPartitions) throws WrongInitialCursorsException, RepositoryProblemException {
    final boolean cursorsMissing = allPartitions.stream().anyMatch(p -> !subscription.getInitialCursors().stream().anyMatch(p::ownsCursor));
    if (cursorsMissing) {
        throw new WrongInitialCursorsException("initial_cursors should contain cursors for all partitions of subscription");
    }
    final boolean hasCursorForWrongPartition = subscription.getInitialCursors().stream().anyMatch(c -> !allPartitions.contains(new EventTypePartition(c.getEventType(), c.getPartition())));
    if (hasCursorForWrongPartition) {
        throw new WrongInitialCursorsException("initial_cursors should contain cursors only for partitions of this subscription");
    }
    if (subscription.getInitialCursors().size() > allPartitions.size()) {
        throw new WrongInitialCursorsException("there should be no more than 1 cursor for each partition in initial_cursors");
    }
    try {
        for (final SubscriptionCursorWithoutToken cursor : subscription.getInitialCursors()) {
            final NakadiCursor nakadiCursor = cursorConverter.convert(cursor);
            if (nakadiCursor.getTimeline().isDeleted()) {
                throw new InvalidCursorException(UNAVAILABLE, nakadiCursor);
            }
            timelineService.getTopicRepository(nakadiCursor.getTimeline()).validateReadCursors(Collections.singletonList(nakadiCursor));
        }
    } catch (final InvalidCursorException ex) {
        throw new WrongInitialCursorsException(ex.getMessage(), ex);
    } catch (final NakadiException ex) {
        throw new RepositoryProblemException("Topic repository problem occurred when validating cursors", ex);
    }
}
Also used : Map(java.util.Map) SubscriptionCursorWithoutToken(org.zalando.nakadi.view.SubscriptionCursorWithoutToken) NakadiCursor(org.zalando.nakadi.domain.NakadiCursor) InvalidCursorException(org.zalando.nakadi.exceptions.InvalidCursorException) WrongInitialCursorsException(org.zalando.nakadi.exceptions.runtime.WrongInitialCursorsException) RepositoryProblemException(org.zalando.nakadi.exceptions.runtime.RepositoryProblemException) EventTypePartition(org.zalando.nakadi.domain.EventTypePartition) NakadiException(org.zalando.nakadi.exceptions.NakadiException) InternalNakadiException(org.zalando.nakadi.exceptions.InternalNakadiException)

Example 52 with NakadiCursor

use of org.zalando.nakadi.domain.NakadiCursor in project nakadi by zalando.

the class PartitionData method onCommitOffset.

CommitResult onCommitOffset(final NakadiCursor offset) {
    boolean seekKafka = false;
    if (comparator.compare(offset, sentOffset) > 0) {
        log.error("Commit in future: current: {}, committed {} will skip sending obsolete data", sentOffset, commitOffset);
        seekKafka = true;
        sentOffset = offset;
    }
    final long committed;
    if (comparator.compare(offset, commitOffset) >= 0) {
        final Set<NakadiCursor> committedCursors = allCursorsOrdered.headSet(offset, true);
        committed = committedCursors.size();
        commitOffset = offset;
        // Operation is cascaded to allCursorsOrdered set.
        committedCursors.clear();
    } else {
        log.error("Commits in past are evil!: Committing in {} while current commit is {}", offset, commitOffset);
        // Commit in past occurred. One should move storage pointer to sentOffset.
        seekKafka = true;
        commitOffset = offset;
        sentOffset = commitOffset;
        allCursorsOrdered.clear();
        nakadiEvents.clear();
        bytesInMemory = 0L;
        committed = 0;
    }
    while (!nakadiEvents.isEmpty() && comparator.compare(nakadiEvents.get(0).getPosition(), commitOffset) <= 0) {
        final ConsumedEvent evt = nakadiEvents.remove(0);
        bytesInMemory -= evt.getEvent().length;
    }
    return new CommitResult(seekKafka, committed);
}
Also used : NakadiCursor(org.zalando.nakadi.domain.NakadiCursor) ConsumedEvent(org.zalando.nakadi.domain.ConsumedEvent)

Example 53 with NakadiCursor

use of org.zalando.nakadi.domain.NakadiCursor in project nakadi by zalando.

the class StreamingState method flushData.

private void flushData(final EventTypePartition pk, final List<ConsumedEvent> data, final Optional<String> metadata) {
    try {
        final NakadiCursor sentOffset = offsets.get(pk).getSentOffset();
        final SubscriptionCursor cursor = getContext().getCursorConverter().convert(sentOffset, getContext().getCursorTokenService().generateToken());
        final int batchSize = getContext().getWriter().writeSubscriptionBatch(getOut().getOutputStream(), cursor, data, metadata);
        bytesSentMeterPerSubscription.mark(batchSize);
        final StreamKpiData kpiData = kpiDataPerEventType.get(pk.getEventType());
        kpiData.addBytesSent(batchSize);
        kpiData.addNumberOfEventsSent(data.size());
        batchesSent++;
    } catch (final IOException e) {
        getLog().error("Failed to write data to output.", e);
        shutdownGracefully("Failed to write data to output");
    }
}
Also used : SubscriptionCursor(org.zalando.nakadi.view.SubscriptionCursor) NakadiCursor(org.zalando.nakadi.domain.NakadiCursor) IOException(java.io.IOException) StreamKpiData(org.zalando.nakadi.metrics.StreamKpiData)

Example 54 with NakadiCursor

use of org.zalando.nakadi.domain.NakadiCursor in project nakadi by zalando.

the class StreamingState method offsetChanged.

void offsetChanged(final EventTypePartition key) {
    if (offsets.containsKey(key)) {
        final PartitionData data = offsets.get(key);
        final NakadiCursor cursor = createNakadiCursor(data.getSubscription().getData());
        final PartitionData.CommitResult commitResult = data.onCommitOffset(cursor);
        if (commitResult.seekOnKafka) {
            reconfigureKafkaConsumer(true);
        }
        if (commitResult.committedCount > 0) {
            committedEvents += commitResult.committedCount;
            this.lastCommitMillis = System.currentTimeMillis();
            streamToOutput();
        }
        if (getParameters().isStreamLimitReached(committedEvents)) {
            final String debugMessage = "Stream limit in events reached: " + committedEvents;
            sendMetadata(debugMessage);
            shutdownGracefully(debugMessage);
        }
        if (releasingPartitions.containsKey(key) && data.isCommitted()) {
            reassignCommitted();
            logPartitionAssignment("New offset received for releasing partition " + key);
        }
    }
}
Also used : NakadiCursor(org.zalando.nakadi.domain.NakadiCursor)

Example 55 with NakadiCursor

use of org.zalando.nakadi.domain.NakadiCursor in project nakadi by zalando.

the class StreamingState method addToStreaming.

private void addToStreaming(final Partition partition, final Map<EventTypePartition, SubscriptionCursorWithoutToken> cursorMap) {
    final NakadiCursor cursor = createNakadiCursor(cursorMap.get(partition.getKey()));
    getLog().info("Adding to streaming {} with start position {}", partition.getKey(), cursor);
    final ZkSubscription<SubscriptionCursorWithoutToken> subscription = getZk().subscribeForOffsetChanges(partition.getKey(), () -> addTask(() -> offsetChanged(partition.getKey())));
    final PartitionData pd = new PartitionData(getComparator(), subscription, cursor, LoggerFactory.getLogger("subscription." + getSessionId() + "." + partition.getKey()), System.currentTimeMillis());
    offsets.put(partition.getKey(), pd);
}
Also used : SubscriptionCursorWithoutToken(org.zalando.nakadi.view.SubscriptionCursorWithoutToken) NakadiCursor(org.zalando.nakadi.domain.NakadiCursor)

Aggregations

NakadiCursor (org.zalando.nakadi.domain.NakadiCursor)56 Timeline (org.zalando.nakadi.domain.Timeline)31 Test (org.junit.Test)27 ShiftedNakadiCursor (org.zalando.nakadi.domain.ShiftedNakadiCursor)21 InvalidCursorException (org.zalando.nakadi.exceptions.InvalidCursorException)14 ServiceUnavailableException (org.zalando.nakadi.exceptions.ServiceUnavailableException)12 SubscriptionCursorWithoutToken (org.zalando.nakadi.view.SubscriptionCursorWithoutToken)12 PartitionStatistics (org.zalando.nakadi.domain.PartitionStatistics)11 List (java.util.List)10 Map (java.util.Map)10 Collectors (java.util.stream.Collectors)10 Storage (org.zalando.nakadi.domain.Storage)10 TopicRepository (org.zalando.nakadi.repository.TopicRepository)10 Optional (java.util.Optional)8 LoggerFactory (org.slf4j.LoggerFactory)8 EventTypePartition (org.zalando.nakadi.domain.EventTypePartition)8 TimelineService (org.zalando.nakadi.service.timeline.TimelineService)8 Collections (java.util.Collections)7 Logger (org.slf4j.Logger)7 InternalNakadiException (org.zalando.nakadi.exceptions.InternalNakadiException)7