use of org.zalando.nakadi.domain.Timeline in project nakadi by zalando.
the class NakadiKafkaConsumer method readEvents.
@Override
public List<ConsumedEvent> readEvents() {
final ConsumerRecords<byte[], byte[]> records = kafkaConsumer.poll(pollTimeout);
if (records.isEmpty()) {
return Collections.emptyList();
}
final ArrayList<ConsumedEvent> result = new ArrayList<>(records.count());
for (final ConsumerRecord<byte[], byte[]> record : records) {
final KafkaCursor cursor = new KafkaCursor(record.topic(), record.partition(), record.offset());
final Timeline timeline = timelineMap.get(new TopicPartition(record.topic(), record.partition()));
result.add(new ConsumedEvent(record.value(), cursor.toNakadiCursor(timeline)));
}
return result;
}
use of org.zalando.nakadi.domain.Timeline in project nakadi by zalando.
the class MultiTimelineEventConsumer method selectCorrectTopicRepo.
private TopicRepository selectCorrectTopicRepo(final NakadiCursor cursor, final Consumer<NakadiCursor> cursorReplacer, final Consumer<NakadiCursor> lastTimelinePosition) throws ServiceUnavailableException {
final List<Timeline> eventTimelines = eventTypeTimelines.get(cursor.getEventType());
final ListIterator<Timeline> itTimeline = eventTimelines.listIterator(eventTimelines.size());
// select last timeline, and then move back until position was found.
Timeline electedTimeline = itTimeline.previous();
while (itTimeline.hasPrevious()) {
final Timeline toCheck = itTimeline.previous();
final NakadiCursor latest = toCheck.calculateNakadiLatestPosition(cursor.getPartition());
if (latest == null) {
electedTimeline = toCheck;
} else if (comparator.compare(latest, cursor) > 0) {
// There is a border case - latest is equal to begin (that means that there are no available events
// there), and one should position on timeline that have something inside.
final NakadiCursor firstItem = timelineService.getTopicRepository(toCheck).loadPartitionStatistics(toCheck, cursor.getPartition()).get().getFirst();
if (comparator.compare(latest, firstItem) >= 0) {
electedTimeline = toCheck;
} else {
LOG.info("Timeline {} is empty, skipping", toCheck);
}
} else {
break;
}
}
final TopicRepository result = timelineService.getTopicRepository(electedTimeline);
if (electedTimeline.getOrder() != cursor.getTimeline().getOrder()) {
// It seems that cursor jumped to different timeline. One need to fetch very first cursor in timeline.
final NakadiCursor replacement = getBeforeFirstCursor(result, electedTimeline, cursor.getPartition());
LOG.info("Replacing cursor because of jumping between timelines from {} to {}", cursor, replacement);
cursorReplacer.accept(replacement);
}
lastTimelinePosition.accept(electedTimeline.calculateNakadiLatestPosition(cursor.getPartition()));
return result;
}
use of org.zalando.nakadi.domain.Timeline in project nakadi by zalando.
the class EventTypeCache method setupInMemoryEventTypeCache.
private LoadingCache<String, CachedValue> setupInMemoryEventTypeCache(final EventTypeRepository eventTypeRepository, final TimelineDbRepository timelineRepository) {
final CacheLoader<String, CachedValue> loader = new CacheLoader<String, CachedValue>() {
public CachedValue load(final String key) throws Exception {
final EventType eventType = eventTypeRepository.findByName(key);
final List<Timeline> timelines = timelineRepository.listTimelinesOrdered(key);
timelineRegistrations.computeIfAbsent(key, n -> timelineSync.registerTimelineChangeListener(n, (etName) -> eventTypeCache.invalidate(etName)));
return new CachedValue(eventType, EventValidation.forType(eventType), timelines);
}
};
return CacheBuilder.newBuilder().maximumSize(CACHE_MAX_SIZE).build(loader);
}
use of org.zalando.nakadi.domain.Timeline in project nakadi by zalando.
the class EventPublisher method submit.
private void submit(final List<BatchItem> batch, final EventType eventType) throws EventPublishingException {
final Timeline activeTimeline = timelineService.getActiveTimeline(eventType);
timelineService.getTopicRepository(eventType).syncPostBatch(activeTimeline.getTopic(), batch);
}
Aggregations