Search in sources :

Example 51 with Subscriber

use of org.reactivestreams.Subscriber in project camel by apache.

the class EventTypeTest method testOnErrorHeaderNotForwarded.

@Test
public void testOnErrorHeaderNotForwarded() throws Exception {
    new RouteBuilder() {

        @Override
        public void configure() throws Exception {
            from("reactive-streams:numbers").to("mock:endpoint");
        }
    }.addRoutesToCamelContext(context);
    Subscriber<Integer> numbers = CamelReactiveStreams.get(context).streamSubscriber("numbers", Integer.class);
    context.start();
    RuntimeException ex = new RuntimeException("1");
    Flowable.just(1).map(n -> {
        if (n == 1) {
            throw ex;
        }
        return n;
    }).subscribe(numbers);
    MockEndpoint endpoint = getMockEndpoint("mock:endpoint");
    endpoint.expectedMessageCount(0);
    endpoint.assertIsSatisfied(200);
}
Also used : CamelReactiveStreams(org.apache.camel.component.reactive.streams.api.CamelReactiveStreams) Flowable(io.reactivex.Flowable) RouteBuilder(org.apache.camel.builder.RouteBuilder) Exchange(org.apache.camel.Exchange) Test(org.junit.Test) CamelTestSupport(org.apache.camel.test.junit4.CamelTestSupport) Subscriber(org.reactivestreams.Subscriber) MockEndpoint(org.apache.camel.component.mock.MockEndpoint) RouteBuilder(org.apache.camel.builder.RouteBuilder) MockEndpoint(org.apache.camel.component.mock.MockEndpoint) Test(org.junit.Test)

Example 52 with Subscriber

use of org.reactivestreams.Subscriber in project ratpack by ratpack.

the class DefaultResponseTransmitter method transmitter.

@Override
public Subscriber<ByteBuf> transmitter(HttpResponseStatus responseStatus) {
    return new Subscriber<ByteBuf>() {

        private Subscription subscription;

        private final AtomicBoolean done = new AtomicBoolean();

        private final ChannelFutureListener cancelOnFailure = future -> {
            if (!future.isSuccess()) {
                cancel();
            }
        };

        private final GenericFutureListener<Future<? super Void>> cancelOnCloseListener = c -> cancel();

        private void cancel() {
            channel.closeFuture().removeListener(cancelOnCloseListener);
            if (done.compareAndSet(false, true)) {
                subscription.cancel();
                post(responseStatus);
            }
        }

        @Override
        public void onSubscribe(Subscription subscription) {
            if (subscription == null) {
                throw new NullPointerException("'subscription' is null");
            }
            if (this.subscription != null) {
                subscription.cancel();
                return;
            }
            this.subscription = subscription;
            ChannelFuture channelFuture = pre(responseStatus, true);
            if (channelFuture == null) {
                subscription.cancel();
                isKeepAlive = false;
                notifyListeners(responseStatus);
            } else {
                channelFuture.addListener(f -> {
                    if (f.isSuccess() && channel.isOpen()) {
                        channel.closeFuture().addListener(cancelOnCloseListener);
                        if (channel.isWritable()) {
                            this.subscription.request(1);
                        }
                        onWritabilityChanged = () -> {
                            if (channel.isWritable() && !done.get()) {
                                this.subscription.request(1);
                            }
                        };
                    } else {
                        cancel();
                    }
                });
            }
        }

        @Override
        public void onNext(ByteBuf o) {
            o.touch();
            if (channel.isOpen()) {
                channel.writeAndFlush(new DefaultHttpContent(o)).addListener(cancelOnFailure);
                if (channel.isWritable()) {
                    subscription.request(1);
                }
            } else {
                o.release();
                cancel();
            }
        }

        @Override
        public void onError(Throwable t) {
            if (t == null) {
                throw new NullPointerException("error is null");
            }
            LOGGER.warn("Exception thrown transmitting stream", t);
            if (done.compareAndSet(false, true)) {
                channel.closeFuture().removeListener(cancelOnCloseListener);
                post(responseStatus);
            }
        }

        @Override
        public void onComplete() {
            if (done.compareAndSet(false, true)) {
                channel.closeFuture().removeListener(cancelOnCloseListener);
                post(responseStatus);
            }
        }
    };
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Subscriber(org.reactivestreams.Subscriber) Subscription(org.reactivestreams.Subscription) ByteBuf(io.netty.buffer.ByteBuf) GenericFutureListener(io.netty.util.concurrent.GenericFutureListener)

Example 53 with Subscriber

use of org.reactivestreams.Subscriber in project ratpack by ratpack.

the class ExecutionBoundPublisher method subscribe.

@Override
public void subscribe(Subscriber<? super T> subscriber) {
    DefaultExecution execution = DefaultExecution.require();
    execution.delimitStream(subscriber::onError, continuation -> publisher.subscribe(new Subscriber<T>() {

        private Subscription subscription;

        private final AtomicBoolean cancelled = new AtomicBoolean();

        private final AtomicBoolean pendingCancelSignal = new AtomicBoolean(true);

        private boolean dispatch(Block block) {
            if (cancelled.get()) {
                return false;
            } else if (execution.isBound()) {
                try {
                    block.execute();
                    return true;
                } catch (Exception e) {
                    // really should not happen
                    throw Exceptions.uncheck(e);
                }
            } else {
                return continuation.event(block);
            }
        }

        @Override
        public void onSubscribe(final Subscription subscription) {
            this.subscription = subscription;
            dispatch(() -> subscriber.onSubscribe(new Subscription() {

                @Override
                public void request(long n) {
                    dispatch(() -> subscription.request(n));
                }

                @Override
                public void cancel() {
                    if (cancelled.compareAndSet(false, true)) {
                        if (execution.isBound()) {
                            subscription.cancel();
                            continuation.complete(Block.noop());
                        } else {
                            pendingCancelSignal.set(true);
                            continuation.complete(() -> {
                                if (pendingCancelSignal.compareAndSet(true, false)) {
                                    subscription.cancel();
                                }
                            });
                        }
                    }
                }
            }));
        }

        @Override
        public void onNext(final T element) {
            boolean added = dispatch(() -> {
                if (cancelled.get()) {
                    dispose(element);
                } else {
                    subscriber.onNext(element);
                }
            });
            if (!added) {
                dispose(element);
                if (cancelled.get()) {
                    if (execution.isBound() && pendingCancelSignal.compareAndSet(true, false)) {
                        subscription.cancel();
                        continuation.complete(Block.noop());
                    }
                }
            }
        }

        private void dispose(T element) {
            try {
                disposer.execute(element);
            } catch (Exception e) {
                DefaultExecution.LOGGER.warn("Exception raised disposing stream item will be ignored - ", e);
            }
        }

        @Override
        public void onComplete() {
            continuation.complete(() -> {
                if (!cancelled.get()) {
                    subscriber.onComplete();
                }
            });
        }

        @Override
        public void onError(final Throwable cause) {
            if (!cancelled.get()) {
                continuation.complete(() -> subscriber.onError(cause));
            }
        }
    }));
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Subscriber(org.reactivestreams.Subscriber) Block(ratpack.func.Block) Subscription(org.reactivestreams.Subscription)

Example 54 with Subscriber

use of org.reactivestreams.Subscriber in project ratpack by ratpack.

the class FanOutPublisher method subscribe.

@Override
public void subscribe(Subscriber<? super T> s) {
    s.onSubscribe(new ManagedSubscription<T>(s, disposer) {

        Iterator<? extends T> iterator;

        Subscription subscription;

        AtomicReference<State> state = new AtomicReference<>(State.UNSUBSCRIBED);

        @Override
        protected void onRequest(long n) {
            if (state.compareAndSet(State.UNSUBSCRIBED, State.PENDING_SUBSCRIBE)) {
                publisher.subscribe(new Subscriber<Iterable<? extends T>>() {

                    @Override
                    public void onSubscribe(Subscription s) {
                        subscription = s;
                        state.set(State.REQUESTED);
                        s.request(1);
                    }

                    @Override
                    public void onNext(Iterable<? extends T> ts) {
                        iterator = ts.iterator();
                        state.set(State.IDLE);
                        drain();
                    }

                    @Override
                    public void onError(Throwable t) {
                        emitError(t);
                        drain();
                    }

                    @Override
                    public void onComplete() {
                        subscription = null;
                        state.compareAndSet(State.REQUESTED, State.IDLE);
                        drain();
                    }
                });
            } else if (iterator != null) {
                drain();
            }
        }

        private void drain() {
            if (state.compareAndSet(State.IDLE, State.EMITTING)) {
                if (isDone()) {
                    if (iterator != null) {
                        while (iterator.hasNext()) {
                            dispose(iterator.next());
                        }
                    }
                    return;
                }
                boolean hasNext = false;
                if (iterator != null) {
                    while ((hasNext = iterator.hasNext()) && shouldEmit()) {
                        emitNext(iterator.next());
                    }
                }
                if (!hasNext) {
                    // iterator is empty
                    if (subscription == null) {
                        emitComplete();
                    } else if (hasDemand()) {
                        state.set(State.REQUESTED);
                        subscription.request(1);
                        return;
                    }
                }
                state.set(State.IDLE);
                if (hasDemand() || isDone()) {
                    drain();
                }
            }
        }

        @Override
        protected void onCancel() {
            if (subscription != null) {
                subscription.cancel();
            }
        }
    });
}
Also used : Subscriber(org.reactivestreams.Subscriber) AtomicReference(java.util.concurrent.atomic.AtomicReference) Subscription(org.reactivestreams.Subscription)

Example 55 with Subscriber

use of org.reactivestreams.Subscriber in project ratpack by ratpack.

the class FlattenPublisher method subscribe.

@Override
public void subscribe(Subscriber<? super T> subscriber) {
    subscriber.onSubscribe(new ManagedSubscription<T>(subscriber, disposer) {

        private Subscription outerSubscription;

        private Subscription innerSubscription;

        private final AtomicReference<State> state = new AtomicReference<>(State.INIT);

        volatile boolean pendingComplete;

        @Override
        protected void onRequest(long n) {
            if (state.compareAndSet(State.INIT, State.SUBSCRIBE)) {
                if (outerSubscription == null) {
                    subscribeUpstream();
                }
            } else if (innerSubscription != null) {
                innerSubscription.request(n);
            } else {
                nextPublisher();
            }
        }

        private void subscribeUpstream() {
            publisher.subscribe(new Subscriber<Publisher<T>>() {

                @Override
                public void onSubscribe(Subscription subscription) {
                    outerSubscription = subscription;
                    outerSubscription.request(1);
                }

                @Override
                public void onNext(Publisher<T> next) {
                    next.subscribe(new Subscriber<T>() {

                        @Override
                        public void onSubscribe(Subscription s) {
                            innerSubscription = s;
                            state.set(State.EMITTING);
                            innerSubscription.request(getDemand());
                        }

                        @Override
                        public void onNext(T t) {
                            emitNext(t);
                        }

                        @Override
                        public void onError(Throwable t) {
                            outerSubscription.cancel();
                            emitError(t);
                        }

                        @Override
                        public void onComplete() {
                            innerSubscription = null;
                            state.set(State.IDLE);
                            nextPublisher();
                        }
                    });
                }

                @Override
                public void onError(Throwable t) {
                    if (innerSubscription != null) {
                        innerSubscription.cancel();
                        innerSubscription = null;
                    }
                    emitError(t);
                }

                @Override
                public void onComplete() {
                    pendingComplete = true;
                    nextPublisher();
                }
            });
        }

        @Override
        protected void onCancel() {
            if (innerSubscription != null) {
                innerSubscription.cancel();
                innerSubscription = null;
            }
            if (outerSubscription != null) {
                outerSubscription.cancel();
                outerSubscription = null;
            }
        }

        private void nextPublisher() {
            if (state.compareAndSet(State.IDLE, State.PENDING)) {
                if (pendingComplete) {
                    emitComplete();
                } else if (hasDemand()) {
                    outerSubscription.request(1);
                } else {
                    state.set(State.IDLE);
                    if (hasDemand()) {
                        nextPublisher();
                    }
                }
            } else if (state.get() == State.PENDING && pendingComplete) {
                emitComplete();
            }
        }
    });
}
Also used : AtomicReference(java.util.concurrent.atomic.AtomicReference) Publisher(org.reactivestreams.Publisher) TransformablePublisher(ratpack.stream.TransformablePublisher) Subscriber(org.reactivestreams.Subscriber) Subscription(org.reactivestreams.Subscription)

Aggregations

Subscriber (org.reactivestreams.Subscriber)92 Subscription (org.reactivestreams.Subscription)56 Test (org.junit.Test)49 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)24 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)23 ProtonClient (io.vertx.proton.ProtonClient)22 ProtonConnection (io.vertx.proton.ProtonConnection)22 Message (org.apache.qpid.proton.message.Message)20 List (java.util.List)18 AmqpValue (org.apache.qpid.proton.amqp.messaging.AmqpValue)18 AtomicReference (java.util.concurrent.atomic.AtomicReference)17 Handler (io.vertx.core.Handler)16 Logger (io.vertx.core.impl.logging.Logger)16 LoggerFactory (io.vertx.core.impl.logging.LoggerFactory)16 ProtonStreams (io.vertx.proton.streams.ProtonStreams)16 ExecutionException (java.util.concurrent.ExecutionException)16 Symbol (org.apache.qpid.proton.amqp.Symbol)16 Section (org.apache.qpid.proton.amqp.messaging.Section)16 ArrayList (java.util.ArrayList)14 Collections (java.util.Collections)13