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

co.paralleluniverse.strands.channels.reactivestreams.ReactiveStreams Maven / Gradle / Ivy

There is a newer version: 0.8.0
Show newest version
/*
 * Quasar: lightweight threads and actors for the JVM.
 * Copyright (c) 2013-2015, Parallel Universe Software Co. All rights reserved.
 * 
 * This program and the accompanying materials are dual-licensed under
 * either the terms of the Eclipse Public License v1.0 as published by
 * the Eclipse Foundation
 *  
 *   or (per the licensee's choosing)
 *  
 * under the terms of the GNU Lesser General Public License version 3.0
 * as published by the Free Software Foundation.
 */
package co.paralleluniverse.strands.channels.reactivestreams;

import co.paralleluniverse.fibers.FiberFactory;
import co.paralleluniverse.strands.SuspendableAction2;
import co.paralleluniverse.strands.channels.Channel;
import co.paralleluniverse.strands.channels.Channels;
import co.paralleluniverse.strands.channels.Channels.OverflowPolicy;
import co.paralleluniverse.strands.channels.ReceivePort;
import co.paralleluniverse.strands.channels.SendPort;
import co.paralleluniverse.strands.channels.Topic;
import org.reactivestreams.Processor;
import org.reactivestreams.Publisher;
import org.reactivestreams.Subscriber;

/**
 * Converts between Quasar channels and reactive streams
 * @author pron
 */
public class ReactiveStreams {
    /**
     * Subscribes to a given {@link Publisher} and return a {@link ReceivePort} to the subscription.
     * This creates an internal single consumer channel that will receive the published elements.
     *
     * @param bufferSize the size of the buffer of the internal channel; may be {@code -1} for unbounded, but may not be {@code 0})
     * @param policy     the {@link OverflowPolicy} of the internal channel.
     * @param publisher  the subscriber
     * @return A {@link ReceivePort} which emits the elements published by the subscriber
     */
    public static  ReceivePort subscribe(int bufferSize, OverflowPolicy policy, Publisher publisher) {
        final Channel channel = Channels.newChannel(bufferSize, policy, true, true);
        final ChannelSubscriber sub = new ChannelSubscriber<>(channel, false);
        publisher.subscribe(sub);
        return sub;
    }

    /**
     * Turns a {@link ReceivePort channel} to a {@link Publisher}. All items sent to the channel will be published by
     * the publisher.
     * 

* The publisher will allow a single subscription, unless the channel is a {@link Channels#isTickerChannel(ReceivePort) ticker channel} * in which case, multiple subscribers will be allowed, and a new {@link Channels#newTickerConsumerFor(Channel) ticker consumer} * will be created for each. *

* Every subscription to the returned publisher creates an internal fiber, that will receive items from the * channel and publish them. * * @param channel the channel * @param ff the {@link FiberFactory} to create the internal fiber(s); if {@code null} then a default factory is used. * @return a new publisher for the channel's items */ public static Publisher toPublisher(ReceivePort channel, FiberFactory ff) { if (Channels.isTickerChannel(channel)) { return new ChannelPublisher(ff, channel, false) { @Override protected ChannelSubscription newChannelSubscription(Subscriber s, Object channel) { return super.newChannelSubscription(s, Channels.newTickerConsumerFor((Channel) channel)); } }; } else return new ChannelPublisher(ff, channel, true); } /** * Turns a {@link ReceivePort channel} to a {@link Publisher}. All items sent to the channel will be published by * the publisher. *

* The publisher will allow a single subscription, unless the channel is a {@link Channels#isTickerChannel(ReceivePort) ticker channel} * in which case, multiple subscribers will be allowed, and a new {@link Channels#newTickerConsumerFor(Channel) ticker consumer} * will be created for each. *

* Every subscription to the returned publisher creates an internal fiber, that will receive items from the * channel and publish them. *

* Calling this method is the same as calling {@link #toPublisher(ReceivePort, FiberFactory) toPublisher(channel, null) * * @param channel the channel * @return a new publisher for the channel's items */ public static Publisher toPublisher(ReceivePort channel) { return toPublisher(channel, null); } /** * Turns a {@link Topic topic} to a {@link Publisher}. All items sent to the topic will be published by * the publisher. *

* A new transfer channel (i.e. a blocking channel with a buffer of size 0) subscribed to the topic will be created for every subscriber. *

* Every subscription to the returned publisher creates an internal fiber, that will receive items from the * subscription's channel and publish them. * * @param topic the topic * @param ff the {@link FiberFactory} to create the internal fiber(s); if {@code null} then a default factory is used. * @return a new publisher for the topic's items */ public static Publisher toPublisher(Topic topic, final FiberFactory ff) { return new ChannelPublisher(ff, topic, false) { @Override protected ChannelSubscription newChannelSubscription(Subscriber s, Object channel) { final Topic topic = (Topic) channel; final Channel ch = Channels.newChannel(0); try { topic.subscribe(ch); return new ChannelSubscription(s, ch) { @Override public void cancel() { super.cancel(); topic.unsubscribe(ch); } }; } catch (Exception e) { topic.unsubscribe(ch); throw e; } } }; } /** * Turns a {@link Topic topic} to a {@link Publisher}. All items sent to the topic will be published by * the publisher. *

* A new transfer channel (i.e. a blocking channel with a buffer of size 0) subscribed to the topic will be created for every subscriber. *

* Every subscription to the returned publisher creates an internal fiber, that will receive items from the * subscription's channel and publish them. *

* Calling this method is the same as calling {@link #toPublisher(ReceivePort, FiberFactory) toPublisher(channel, null) * * @param topic the topic * @return a new publisher for the topic's items */ public static Publisher toPublisher(Topic topic) { return toPublisher(topic, null); } /** * Turns a {@link Channels#fiberTransform(ReceivePort, SendPort, SuspendableAction2) transformer} into a {@link Publisher}. * The transformer will run in its own fiber. * * @param the type of elements flowing into the transformer * @param the type of elements flowing out of the transformer * @param ff the {@link FiberFactory} to create the internal fiber(s); if {@code null} then a default factory is used. * @param bufferSize the size of the buffer of the internal channel; may be {@code -1} for unbounded, but may not be {@code 0}) * @param policy the {@link OverflowPolicy} of the internal channel. * @param batch if the channel has a bounded buffer, whether to request further elements from the publisher in batches * whenever the channel's buffer is depleted, or after consuming each element. * @param transformer a function that reads from it's input channel and writes to its output channel * @return a {@code Processor} running the given transformer. */ public static Processor toProcessor(FiberFactory ff, int bufferSize, OverflowPolicy policy, SuspendableAction2, ? extends SendPort> transformer) { final Channel in = Channels.newChannel(bufferSize, policy, true, true); final Channel out = Channels.newChannel(bufferSize, policy, true, true); return new ChannelProcessor(ff, false, in, out, transformer); } /** * Turns a {@link Channels#fiberTransform(ReceivePort, SendPort, SuspendableAction2) transformer} into a {@link Publisher}. * The transformer will run in its own fiber. *

* Same as calling * {@link #toProcessor(FiberFactory, int, OverflowPolicy, boolean, SuspendableAction2) toProcessor(null, bufferSize, policy, transformer) * * @param the type of elements flowing into the transformer * @param the type of elements flowing out of the transformer * @param ff the {@link FiberFactory} to create the internal fiber(s); if {@code null} then a default factory is used. * @param bufferSize the size of the buffer of the internal channel; may be {@code -1} for unbounded, but may not be {@code 0}) * @param policy the {@link OverflowPolicy} of the internal channel. * @param batch if the channel has a bounded buffer, whether to request further elements from the publisher in batches * whenever the channel's buffer is depleted, or after consuming each element. * @param transformer a function that reads from it's input channel and writes to its output channel * @return a {@code Processor} running the given transformer. */ public static Processor toProcessor(int bufferSize, OverflowPolicy policy, SuspendableAction2, ? extends SendPort> transformer) { return toProcessor(null, bufferSize, policy, transformer); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy