Search in sources :

Example 1 with Position

use of cz.o2.proxima.storage.commitlog.Position in project proxima-platform by O2-Czech-Republic.

the class LocalKafkaCommitLogDescriptorTest method testOnlineObserveWithRebalanceResetsOffsetCommitter.

@Test(timeout = 100000)
public void testOnlineObserveWithRebalanceResetsOffsetCommitter() throws InterruptedException {
    int numWrites = 5;
    Accessor accessor = kafka.createAccessor(direct, createTestFamily(entity, storageUri, cfg(Pair.of(LocalKafkaCommitLogDescriptor.CFG_NUM_PARTITIONS, 3), // poll single record to commit it in atomic way
    Pair.of(KafkaAccessor.MAX_POLL_RECORDS, 1))));
    final CountDownLatch latch = new CountDownLatch(numWrites);
    AtomicInteger consumed = new AtomicInteger();
    List<OnNextContext> unconfirmed = Collections.synchronizedList(new ArrayList<>());
    CommitLogObserver observer = new CommitLogObserver() {

        @Override
        public boolean onNext(StreamElement ingest, OnNextContext context) {
            switch(consumed.getAndIncrement()) {
                case 0:
                    // we must confirm the first message to create a committed position
                    context.confirm();
                    break;
                case 2:
                    throw new RuntimeException("Failing first consumer!");
                default:
                    unconfirmed.add(context);
                    break;
            }
            if (consumed.get() == numWrites) {
                unconfirmed.forEach(OnNextContext::confirm);
            }
            latch.countDown();
            return true;
        }

        @Override
        public void onCompleted() {
        }

        @Override
        public boolean onError(Throwable error) {
            return true;
        }
    };
    testOnlineObserveWithRebalanceResetsOffsetCommitterWithObserver(observer, accessor, numWrites);
    latch.await();
    assertEquals("Invalid committed offests: " + accessor.committedOffsets, 3, accessor.committedOffsets.values().stream().mapToInt(AtomicInteger::get).sum());
}
Also used : CommitLogObserver(cz.o2.proxima.direct.commitlog.CommitLogObserver) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) OnNextContext(cz.o2.proxima.direct.commitlog.CommitLogObserver.OnNextContext) StreamElement(cz.o2.proxima.storage.StreamElement) CountDownLatch(java.util.concurrent.CountDownLatch) Accessor(cz.o2.proxima.direct.kafka.LocalKafkaCommitLogDescriptor.Accessor) Test(org.junit.Test)

Example 2 with Position

use of cz.o2.proxima.storage.commitlog.Position in project proxima-platform by O2-Czech-Republic.

the class PubSubReader method observeBulk.

private ObserveHandle observeBulk(@Nullable String name, Position position, boolean stopAtCurrent, long minWatermark, CommitLogObserver observer) {
    validateNotStopAtCurrent(stopAtCurrent);
    validatePosition(position);
    AtomicReference<List<AckReplyConsumer>> unconfirmed = new AtomicReference<>(new ArrayList<>());
    Object lock = new Object();
    Object listLock = new Object();
    AtomicLong globalOffset = new AtomicLong();
    String consumerName = asConsumerName(name);
    AtomicLong committedWatermark = new AtomicLong(minWatermark);
    PubSubPartition partition = new PubSubPartition(consumerName);
    return consume(consumerName, (e, w, c) -> {
        final long confirmUntil;
        synchronized (listLock) {
            List<AckReplyConsumer> list = unconfirmed.get();
            list.add(c);
            confirmUntil = list.size() + globalOffset.get();
        }
        OffsetCommitter committer = createBulkCommitter(listLock, confirmUntil, globalOffset, unconfirmed, w, committedWatermark);
        // ensure explicit synchronization here
        synchronized (lock) {
            try {
                Offset offset = new PubSubOffset(consumerName, w.getWatermark());
                if (!observer.onNext(e, asOnNextContext(committer, offset))) {
                    observer.onCompleted();
                    return false;
                }
                return true;
            } catch (Exception ex) {
                log.error("Error calling on next", ex);
                committer.fail(ex);
                throw new RuntimeException(ex);
            }
        }
    }, observer::onError, () -> observer.onRepartition(asRepartitionContext(Arrays.asList(partition))), () -> observer.onRepartition(asRepartitionContext(Arrays.asList(partition))), observer::onCancelled, committedWatermark);
}
Also used : AtomicReference(java.util.concurrent.atomic.AtomicReference) AlreadyExistsException(com.google.api.gax.rpc.AlreadyExistsException) IOException(java.io.IOException) Offset(cz.o2.proxima.direct.commitlog.Offset) AtomicLong(java.util.concurrent.atomic.AtomicLong) List(java.util.List) ArrayList(java.util.ArrayList) AckReplyConsumer(com.google.cloud.pubsub.v1.AckReplyConsumer) OffsetCommitter(cz.o2.proxima.direct.commitlog.CommitLogObserver.OffsetCommitter)

Example 3 with Position

use of cz.o2.proxima.storage.commitlog.Position in project proxima-platform by O2-Czech-Republic.

the class ListCommitLog method observe.

@Override
public ObserveHandle observe(@Nullable String name, Position position, CommitLogObserver observer) {
    String consumerName = name == null ? UUID.randomUUID().toString() : name;
    Consumer consumer = CONSUMERS.get(uuid).computeIfAbsent(consumerName, k -> new Consumer(uuid, consumerName, watermarkEstimator));
    ListObserveHandle handle = new ListObserveHandle(uuid, consumerName);
    pushTo((element, offset) -> {
        if (handle.isClosed()) {
            return false;
        }
        final CommitLogObserver.OffsetCommitter committer = (succ, exc) -> {
            if (exc != null) {
                observer.onError(exc);
            }
        };
        final boolean acceptable;
        OnNextContext context = null;
        synchronized (consumer) {
            acceptable = (externalizableOffsets || !consumer.getAckedOffsets().contains(offset) && !consumer.getInflightOffsets().contains(offset));
            if (acceptable) {
                context = consumer.asOnNextContext(committer, offset);
            }
        }
        if (acceptable) {
            return observer.onNext(element, context);
        }
        return true;
    }, externalizableOffsets ? () -> true : allMatchOffset(consumer::isAcked), observer::onCompleted, observer::onCancelled);
    return handle;
}
Also used : CommitLogObserver(cz.o2.proxima.direct.commitlog.CommitLogObserver) Context(cz.o2.proxima.direct.core.Context) IntStream(java.util.stream.IntStream) Iterables(com.google.common.collect.Iterables) Getter(lombok.Getter) Partition(cz.o2.proxima.storage.Partition) OffsetCommitter(cz.o2.proxima.direct.commitlog.CommitLogObserver.OffsetCommitter) URISyntaxException(java.net.URISyntaxException) HashMap(java.util.HashMap) Function(java.util.function.Function) ObserverUtils(cz.o2.proxima.direct.commitlog.ObserverUtils) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) StreamElement(cz.o2.proxima.storage.StreamElement) WatermarkEstimator(cz.o2.proxima.time.WatermarkEstimator) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) Watermarks(cz.o2.proxima.time.Watermarks) UnaryPredicate(cz.o2.proxima.functional.UnaryPredicate) SerializationException(cz.o2.proxima.scheme.SerializationException) URI(java.net.URI) TypeReference(com.fasterxml.jackson.core.type.TypeReference) CommitLogReader(cz.o2.proxima.direct.commitlog.CommitLogReader) Nonnull(javax.annotation.Nonnull) ExecutorService(java.util.concurrent.ExecutorService) Nullable(javax.annotation.Nullable) OffsetExternalizer(cz.o2.proxima.direct.commitlog.OffsetExternalizer) BiFunction(cz.o2.proxima.functional.BiFunction) Collection(java.util.Collection) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) MoreObjects(com.google.common.base.MoreObjects) CommitLogObserver(cz.o2.proxima.direct.commitlog.CommitLogObserver) Set(java.util.Set) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) ObserveHandle(cz.o2.proxima.direct.commitlog.ObserveHandle) UUID(java.util.UUID) Collectors(java.util.stream.Collectors) Offset(cz.o2.proxima.direct.commitlog.Offset) Objects(java.util.Objects) List(java.util.List) OnNextContext(cz.o2.proxima.direct.commitlog.CommitLogObserver.OnNextContext) Preconditions(com.google.common.base.Preconditions) VisibleForTesting(com.google.common.annotations.VisibleForTesting) Collections(java.util.Collections) Position(cz.o2.proxima.storage.commitlog.Position) ObserverUtils.asRepartitionContext(cz.o2.proxima.direct.commitlog.ObserverUtils.asRepartitionContext) OnNextContext(cz.o2.proxima.direct.commitlog.CommitLogObserver.OnNextContext) OffsetCommitter(cz.o2.proxima.direct.commitlog.CommitLogObserver.OffsetCommitter)

Example 4 with Position

use of cz.o2.proxima.storage.commitlog.Position in project proxima-platform by O2-Czech-Republic.

the class DirectUnboundedSource method createReader.

@Override
public UnboundedReader<StreamElement> createReader(PipelineOptions po, Checkpoint cmt) {
    Offset offset = cmt == null ? null : cmt.getOffset();
    long readerLimit = cmt == null ? limit : cmt.getLimit();
    CommitLogReader reader = reader();
    log.info("Created reader reading from {} with offset {} and limit {}", reader.getUri(), offset, readerLimit);
    return BeamCommitLogReader.unbounded(this, name, reader, position, eventTime, readerLimit, partition, offset);
}
Also used : CommitLogReader(cz.o2.proxima.direct.commitlog.CommitLogReader) Offset(cz.o2.proxima.direct.commitlog.Offset)

Example 5 with Position

use of cz.o2.proxima.storage.commitlog.Position in project proxima-platform by O2-Czech-Republic.

the class DirectDataAccessorWrapper method createStream.

@Override
public PCollection<StreamElement> createStream(String name, Pipeline pipeline, Position position, boolean stopAtCurrent, boolean eventTime, long limit) {
    CommitLogReader reader = direct.getCommitLogReader(context).orElseThrow(() -> new IllegalArgumentException("Cannot create commit log from " + direct));
    final PCollection<StreamElement> ret;
    if (stopAtCurrent) {
        // bounded
        // FIXME: this should be converted to SDF
        // we need to support CommitLogReader#fetchOffsets() for that
        // see https://github.com/O2-Czech-Republic/proxima-platform/issues/191
        // once that is resolved, we can proceed
        ret = pipeline.apply("ReadBounded:" + uri, Read.from(DirectBoundedSource.of(factory, name, reader, position, limit)));
    } else {
        // unbounded
        ret = pipeline.apply("ReadUnbounded:" + uri, CommitLogRead.of(name, position, limit, factory, reader));
    }
    return ret.setCoder(StreamElementCoder.of(factory)).setTypeDescriptor(TypeDescriptor.of(StreamElement.class));
}
Also used : CommitLogReader(cz.o2.proxima.direct.commitlog.CommitLogReader) StreamElement(cz.o2.proxima.storage.StreamElement)

Aggregations

StreamElement (cz.o2.proxima.storage.StreamElement)6 VisibleForTesting (com.google.common.annotations.VisibleForTesting)5 CommitLogReader (cz.o2.proxima.direct.commitlog.CommitLogReader)5 Offset (cz.o2.proxima.direct.commitlog.Offset)5 List (java.util.List)5 CommitLogObserver (cz.o2.proxima.direct.commitlog.CommitLogObserver)4 ObserveHandle (cz.o2.proxima.direct.commitlog.ObserveHandle)4 Partition (cz.o2.proxima.storage.Partition)4 Position (cz.o2.proxima.storage.commitlog.Position)4 ArrayList (java.util.ArrayList)4 Collection (java.util.Collection)4 Collections (java.util.Collections)4 HashMap (java.util.HashMap)4 Objects (java.util.Objects)4 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)4 AtomicReference (java.util.concurrent.atomic.AtomicReference)4 TopicPartition (org.apache.kafka.common.TopicPartition)4 Preconditions (com.google.common.base.Preconditions)3 Context (cz.o2.proxima.direct.core.Context)3 WatermarkEstimator (cz.o2.proxima.time.WatermarkEstimator)3