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

io.descoped.rawdata.api.RawdataProducer Maven / Gradle / Ivy

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

import de.huxhorn.sulky.ulid.ULID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.concurrent.CompletableFuture;

public interface RawdataProducer extends AutoCloseable {

    Logger LOG = LoggerFactory.getLogger(RawdataProducer.class);

    /**
     * @return the topic on which this producer will publish messages.
     */
    String topic();

    /**
     * Publish messages. Published content will be assigned an ulid if it is missing from any of the provided messages.
     *
     * @param messages a list of messages
     * @throws RawdataClosedException if the producer was closed before or during this call.
     */
    default void publish(List messages) throws RawdataClosedException {
        publish(messages.toArray(new RawdataMessage[0]));
    }

    /**
     * Publish messages. Published content will be assigned an ulid if it is missing from any of the provided messages.
     *
     * @param messages a list of messages
     * @throws RawdataClosedException if the producer was closed before or during this call.
     */
    void publish(RawdataMessage... messages) throws RawdataClosedException;

    /**
     * Asynchronously publish all messages. Published content will be assigned an ulid if it is missing from any of the provided messages.
     *
     * @param messages a list of messages
     * @return a completable futures representing the completeness of the async-function.
     */
    default CompletableFuture publishAsync(List messages) {
        return publishAsync(messages.toArray(new RawdataMessage[messages.size()]));
    }

    /**
     * Asynchronously publish all messages. Published content will be assigned an ulid if it is missing from any of the provided messages.
     *
     * @param messages a list of messages
     * @return a completable futures representing the completeness of the async-function.
     */
    CompletableFuture publishAsync(RawdataMessage... messages);

    /**
     * Returns whether or not the producer is closed.
     *
     * @return whether the producer is closed.
     */
    boolean isClosed();

    @Override
    void close();

    /**
     * Generate a new unique ulid. If the newly generated ulid has a new timestamp than the previous one, then the very
     * least significant bit will be set to 1 (which is higher than beginning-of-time ulid used by consumer).
     *
     * @param generator    the ulid generator
     * @param previousUlid the previous ulid in the sequence
     * @return the generated ulid
     */
    static ULID.Value nextMonotonicUlid(ULID generator, ULID.Value previousUlid) {
        /*
         * Will spin until time ticks if next value overflows.
         * Although theoretically possible, it is extremely unlikely that the loop will ever spin
         */
        ULID.Value value;
        do {
            long timestamp = System.currentTimeMillis();
            long diff = timestamp - previousUlid.timestamp();
            if (diff < 0) {
                if (diff < -(30 * 1000)) {
                    throw new IllegalStateException(String.format("Previous timestamp is in the future. Diff %d ms", -diff));
                }
                LOG.debug("Previous timestamp is in the future, waiting for time to catch up. Diff {} ms", -diff);
                try {
                    Thread.sleep(-diff);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            } else if (diff > 0) {
                // start at lsb 1, to avoid inclusive/exclusive semantics when searching
                return new ULID.Value((timestamp << 16) & 0xFFFFFFFFFFFF0000L, 1L);
            }
            // diff == 0
            value = generator.nextStrictlyMonotonicValue(previousUlid, timestamp).orElse(null);
        } while (value == null);
        return value;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy