All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.descoped.rawdata.memory.MemoryRawdataConsumer Maven / Gradle / Ivy

The newest version!
package io.descoped.rawdata.memory;

import io.descoped.rawdata.api.RawdataClosedException;
import io.descoped.rawdata.api.RawdataConsumer;
import io.descoped.rawdata.api.RawdataMessage;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;

class MemoryRawdataConsumer implements RawdataConsumer {

    final MemoryRawdataTopic topic;
    final Consumer closeAction;
    final AtomicReference position = new AtomicReference<>();
    final AtomicBoolean closed = new AtomicBoolean(false);

    MemoryRawdataConsumer(MemoryRawdataTopic topic, MemoryCursor initialPosition, Consumer closeAction) {
        this.topic = topic;
        this.closeAction = closeAction;
        if (initialPosition == null) {
            initialPosition = new MemoryCursor(RawdataConsumer.beginningOfTime(), true, true);
        }
        this.position.set(initialPosition);
    }

    @Override
    public String topic() {
        return topic.topic;
    }

    @Override
    public RawdataMessage receive(int timeout, TimeUnit unit) throws InterruptedException, RawdataClosedException {
        long expireTimeNano = System.nanoTime() + unit.toNanos(timeout);
        topic.tryLock(5, TimeUnit.SECONDS);
        try {
            while (!topic.hasNext(position.get())) {
                if (isClosed()) {
                    throw new RawdataClosedException();
                }
                long durationNano = expireTimeNano - System.nanoTime();
                if (durationNano <= 0) {
                    return null; // timeout
                }
                topic.awaitProduction(durationNano, TimeUnit.NANOSECONDS);
            }
            RawdataMessage message = topic.readNext(position.get());
            position.set(new MemoryCursor(message.ulid(), false, true));
            return message;
        } finally {
            topic.unlock();
        }
    }

    @Override
    public CompletableFuture receiveAsync() {
        return CompletableFuture.supplyAsync(() -> {
            try {
                return receive(5, TimeUnit.MINUTES);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
    }

    @Override
    public void seek(long timestamp) {
        position.set(new MemoryCursor(RawdataConsumer.beginningOf(timestamp), true, true));
    }

    @Override
    public String toString() {
        return "MemoryRawdataConsumer{" +
                "position=" + position +
                ", closed=" + closed +
                '}';
    }

    @Override
    public boolean isClosed() {
        return closed.get();
    }

    @Override
    public void close() {
        closeAction.accept(this);
        closed.set(true);
        if (topic.tryLock()) {
            try {
                topic.signalProduction();
            } finally {
                topic.unlock();
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy