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

oracle.kv.impl.async.AsyncPublisherImpl Maven / Gradle / Ivy

/*-
 * Copyright (C) 2011, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This file was distributed by Oracle as part of a version of Oracle NoSQL
 * Database made available at:
 *
 * http://www.oracle.com/technetwork/database/database-technologies/nosqldb/downloads/index.html
 *
 * Please see the LICENSE file included in the top-level directory of the
 * appropriate version of Oracle NoSQL Database for a copy of the license and
 * additional information.
 */

package oracle.kv.impl.async;

import java.util.Objects;
import java.util.function.Supplier;
import java.util.logging.Logger;

import org.reactivestreams.Publisher;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;

/**
 * An implementation of {@link Publisher} that creates a single subscription
 * using an {@link AsyncIterationHandleImpl}. Calls {@link Subscriber#onError}
 * with an {@link IllegalStateException} if {@link #subscribe} is called more
 * than once.
 *
 * @param  the element type
 */
public class AsyncPublisherImpl implements Publisher {
    private final Supplier> handleSupplier;
    private boolean used;
    private final Logger logger;

    private AsyncPublisherImpl(
        Supplier> handleSupplier, Logger logger) {

        this.handleSupplier = handleSupplier;
        this.logger = logger;
    }

    /**
     * Creates an instance that calls the argument to create the iteration
     * handle.
     *
     * @param  the element type
     * @param handleSupplier for creating the iteration handle
     * @param logger for logging messages
     * @return the publisher
     */
    public static  Publisher newInstance(
        Supplier> handleSupplier, Logger logger) {

        return new AsyncPublisherImpl<>(handleSupplier, logger);
    }

    @Override
    public void subscribe(Subscriber subscriber) {
        Objects.requireNonNull(subscriber, "The subscriber must not be null");
        synchronized (this) {
            if (used) {

                /*
                 * Reactive Streams Subscriber Rule 1.10 says subscribe must
                 * not be called more than once with the same subscriber.
                 * It is not worth tracking if the subscription is already
                 * complete in this case -- just log the incorrect usage.
                 */
                logger.warning("Calling subscribe more than once on this" +
                               " publisher is not permitted" +
                               ", subscriber: " + subscriber);
                return;
            }
            used = true;
        }
        final AsyncIterationHandleImpl handle;
        try {
            handle = handleSupplier.get();
        } catch (Exception e) {

            /* Rule 1.9: Call onSubscribe before onError */
            subscriber.onSubscribe(
                new Subscription() {
                    @Override public void cancel() { }
                    @Override public void request(long n) { }
                });
            subscriber.onError(e);
            return;
        }
        handle.subscribe(subscriber);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy