Java Code Examples for io.smallrye.mutiny.subscription.BackPressureStrategy

The following examples show how to use io.smallrye.mutiny.subscription.BackPressureStrategy. These examples are extracted from open source projects. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
@Test
public void testWithoutBackPressure() {
    MultiAssertSubscriber<Integer> subscriber = Multi.createFrom().<Integer> emitter(emitter -> {
        IntStream.range(0, 1000).forEach(emitter::emit);
        emitter.complete();
    }, BackPressureStrategy.IGNORE).subscribe()
            .withSubscriber(MultiAssertSubscriber.create())
            .assertCompletedSuccessfully();
    assertThat(subscriber.items()).hasSize(1000);

    subscriber = Multi.createFrom().<Integer> emitter(emitter -> {
        IntStream.range(0, 1000).forEach(emitter::emit);
        emitter.complete();
    }, BackPressureStrategy.IGNORE).subscribe()
            .withSubscriber(MultiAssertSubscriber.create(5))
            // The request is ignored by the strategy.
            .assertCompletedSuccessfully();
    assertThat(subscriber.items()).hasSize(1000);
}
 
Example 2
@Test
public void testDropBackPressureBehavior() {
    Multi<Integer> multi = Multi.createFrom().emitter(e -> e.emit(1).emit(2).emit(3).complete(), BackPressureStrategy.DROP);

    multi.subscribe().withSubscriber(MultiAssertSubscriber.create(1))
            .assertSubscribed()
            .assertReceived(1)
            .request(2)
            .assertReceived(1)
            .assertCompletedSuccessfully();

    multi.subscribe().withSubscriber(MultiAssertSubscriber.create(3))
            .assertSubscribed()
            .assertReceived(1, 2, 3)
            .request(2)
            .assertReceived(1, 2, 3)
            .assertCompletedSuccessfully();

    multi.subscribe().withSubscriber(MultiAssertSubscriber.create(0))
            .assertSubscribed()
            .assertHasNotReceivedAnyItem()
            .request(2)
            .assertHasNotReceivedAnyItem()
            .assertCompletedSuccessfully();
}
 
Example 3
@Test
public void testErrorBackPressureBehavior() {
    Multi<Integer> multi = Multi.createFrom().emitter(e -> e.emit(1).emit(2).emit(3).complete(),
            BackPressureStrategy.ERROR);

    multi.subscribe().withSubscriber(MultiAssertSubscriber.create(1))
            .assertSubscribed()
            .assertReceived(1)
            .assertHasFailedWith(BackPressureFailure.class, "requests");

    multi.subscribe().withSubscriber(MultiAssertSubscriber.create(3))
            .assertSubscribed()
            .assertReceived(1, 2, 3)
            .assertCompletedSuccessfully();

    Multi.createFrom().emitter(MultiEmitter::complete, BackPressureStrategy.ERROR)
            .subscribe().withSubscriber(MultiAssertSubscriber.create())
            .assertCompletedSuccessfully()
            .assertHasNotReceivedAnyItem();
}
 
Example 4
public static <T> Multi<T> create(Consumer<MultiEmitter<? super T>> deferred, long bufferSize) {
    // ThrowingEmitter works by wrapping around a delegate emitter and tracking the requests from downstream so that it can throw an exception from emit() if there aren't sufficient requests

    // If there's no buffer we can use IGNORE since we do our own counting of requests, otherwise we need the delegate to buffer requests for us
    BackPressureStrategy backPressureStrategy = bufferSize == 0 ? BackPressureStrategy.IGNORE : BackPressureStrategy.BUFFER;

    // Use deferred so that we can add a separate on request callback for each subscriber
    return Multi.createFrom().deferred(() -> {

        ThrowingEmitter<T> throwingEmitter = new ThrowingEmitter<>(bufferSize);

        // When someone subscribes, wrap the emitter with our throwing emitter
        Consumer<MultiEmitter<? super T>> consumer = emitter -> {
            throwingEmitter.delegate = emitter;
            deferred.accept(throwingEmitter);
        };

        // Create the Multi and attach the request callback
        return Multi.createFrom().emitter(consumer, backPressureStrategy).on().request(throwingEmitter::request);
    });
}
 
Example 5
Source Project: smallrye-mutiny   Source File: MultiCreate.java    License: Apache License 2.0 5 votes vote down vote up
/**
 * Creates a {@link Multi} from the given {@link CompletionStage} or {@link CompletableFuture}. The future is
 * created by invoking the passed {@link Supplier} <strong>lazily</strong> at subscription time.
 * <p>
 * The produced {@code Multi} emits the item of the passed {@link CompletionStage} followed by the completion
 * event. If the {@link CompletionStage} never completes (or failed), the produced {@link Multi} would not emit
 * an item or a failure.
 * <p>
 * Cancelling the subscription on the produced {@link Multi} cancels the passed {@link CompletionStage}
 * (calling {@link CompletableFuture#cancel(boolean)} on the future retrieved using
 * {@link CompletionStage#toCompletableFuture()}.
 * <p>
 * If the produced stage has already been completed (or failed), the produced {@link Multi} sends the item or
 * failure immediately after subscription. In the case of item, the event is followed by the completion event. If
 * the produced stage is not yet completed, the subscriber's callbacks are called on the thread used
 * by the passed {@link CompletionStage}.
 * <p>
 * If the produced completion stage redeems {@code null}, it fires the completion event without any item.
 * <p>
 * If the supplier throws an exception, a failure event with the exception is fired. If the supplier produces
 * {@code null}, a failure event containing a {@link NullPointerException} is fired.
 *
 * @param supplier the supplier, must not be {@code null}, must not produce {@code null}
 * @param <T> the type of item
 * @return the produced {@link Multi}
 */
public <T> Multi<T> completionStage(Supplier<? extends CompletionStage<? extends T>> supplier) {
    nonNull(supplier, "supplier");
    return emitter(emitter -> {
        CompletionStage<? extends T> stage;
        try {
            stage = supplier.get();
        } catch (Throwable e) {
            emitter.fail(e);
            return;
        }
        if (stage == null) {
            throw new NullPointerException(SUPPLIER_PRODUCED_NULL);
        }
        emitter.onTermination(() -> stage.toCompletableFuture().cancel(false));
        stage.whenComplete((r, f) -> {
            if (f != null) {
                if (f instanceof CompletionException) {
                    emitter.fail(f.getCause());
                } else {
                    emitter.fail(f);
                }
            } else if (r != null) {
                emitter.emit(r);
            }
            emitter.complete();
        });
    }, BackPressureStrategy.LATEST);
}
 
Example 6
Source Project: smallrye-mutiny   Source File: MultiOnItem.java    License: Apache License 2.0 5 votes vote down vote up
/**
 * Configures the <em>mapper</em> of the <em>flatMap</em> operation.
 * The mapper returns a {@link CompletionStage} and is called for each item emitted by the upstream {@link Multi}.
 *
 * @param mapper the mapper, must not be {@code null}, must not produce {@code null}
 * @param <O> the type of item emitted by the {@link CompletionStage} produced by the mapper.
 * @return the object to configure the flatten behavior.
 */
public <O> MultiFlatten<T, O> produceCompletionStage(
        Function<? super T, ? extends CompletionStage<? extends O>> mapper) {
    nonNull(mapper, "mapper");
    Function<? super T, ? extends Publisher<? extends O>> wrapper = res -> Multi.createFrom().emitter(emitter -> {
        CompletionStage<? extends O> stage;
        try {
            stage = mapper.apply(res);
        } catch (Throwable e) {
            emitter.fail(e);
            return;
        }
        if (stage == null) {
            throw new NullPointerException(SUPPLIER_PRODUCED_NULL);
        }

        emitter.onTermination(() -> stage.toCompletableFuture().cancel(false));
        stage.whenComplete((r, f) -> {
            if (f != null) {
                emitter.fail(f);
            } else if (r != null) {
                emitter.emit(r);
                emitter.complete();
            } else {
                // failure on `null`
                emitter.fail(new NullPointerException("The completion stage redeemed `null`"));
            }
        });
    }, BackPressureStrategy.LATEST);

    return new MultiFlatten<>(upstream, wrapper, 1, false);
}
 
Example 7
@Test
public void testIgnoreBackPressureBehavior() {
    Multi<Integer> multi = Multi.createFrom().emitter(e -> e.emit(1).emit(2).emit(3).complete(),
            BackPressureStrategy.IGNORE);

    multi.subscribe().withSubscriber(MultiAssertSubscriber.create(1))
            .assertSubscribed()
            .assertReceived(1, 2, 3)
            .request(2)
            .assertReceived(1, 2, 3)
            .assertCompletedSuccessfully();
}
 
Example 8
@Test
public void testLatestBackPressureBehavior() {
    Multi<Integer> multi = Multi.createFrom().emitter(e -> e.emit(1).emit(2).emit(3).complete(),
            BackPressureStrategy.LATEST);

    multi.subscribe().withSubscriber(MultiAssertSubscriber.create(1))
            .assertSubscribed()
            .assertReceived(1)
            .request(2)
            .assertReceived(1, 3)
            .assertCompletedSuccessfully();
}
 
Example 9
@Test
public void testWithLatestBackPressure() {
    MultiAssertSubscriber<Integer> subscriber = Multi.createFrom().<Integer> emitter(emitter -> {
        IntStream.range(0, 1000).forEach(emitter::emit);
        emitter.complete();
    }, BackPressureStrategy.LATEST).subscribe()
            .withSubscriber(MultiAssertSubscriber.create(20))
            .request(Long.MAX_VALUE)
            .assertCompletedSuccessfully();
    // 21 because the 20 first are consumed, and then only the latest is kept.
    assertThat(subscriber.items()).hasSize(21);

    subscriber = Multi.createFrom().<Integer> emitter(emitter -> {
        IntStream.range(0, 1000).forEach(emitter::emit);
        emitter.complete();
    }, BackPressureStrategy.LATEST).subscribe()
            .withSubscriber(MultiAssertSubscriber.create())
            .request(20)
            .request(Long.MAX_VALUE)
            .assertCompletedSuccessfully();
    assertThat(subscriber.items()).hasSize(1).containsExactly(999);

    Multi.createFrom().<Integer> emitter(MultiEmitter::complete, BackPressureStrategy.LATEST)
            .subscribe().withSubscriber(MultiAssertSubscriber.create(20))
            .assertCompletedSuccessfully()
            .assertHasNotReceivedAnyItem();

    subscriber = Multi.createFrom().<Integer> emitter(emitter -> {
        IntStream.range(0, 1000).forEach(emitter::emit);
        emitter.fail(new IOException("boom"));
    }, BackPressureStrategy.LATEST).subscribe()
            .withSubscriber(MultiAssertSubscriber.create())
            .request(20)
            .request(Long.MAX_VALUE)
            .assertHasFailedWith(IOException.class, "boom");
    assertThat(subscriber.items()).hasSize(1).containsExactly(999);

}
 
Example 10
@Test
public void testWithDropBackPressure() {
    MultiAssertSubscriber<Integer> subscriber = Multi.createFrom().<Integer> emitter(emitter -> {
        IntStream.range(0, 1000).forEach(emitter::emit);
        emitter.complete();
    }, BackPressureStrategy.DROP).subscribe()
            .withSubscriber(MultiAssertSubscriber.create(20))
            .request(Long.MAX_VALUE)
            .assertCompletedSuccessfully();
    // 20 because the 20 first are consumed, others are dropped
    assertThat(subscriber.items()).hasSize(20);

    subscriber = Multi.createFrom().<Integer> emitter(emitter -> {
        IntStream.range(0, 1000).forEach(emitter::emit);
        emitter.complete();
    }, BackPressureStrategy.DROP).subscribe()
            .withSubscriber(MultiAssertSubscriber.create())
            .request(20)
            .request(Long.MAX_VALUE)
            .assertCompletedSuccessfully();
    assertThat(subscriber.items()).isEmpty();

    Multi.createFrom().<Integer> emitter(MultiEmitter::complete, BackPressureStrategy.DROP)
            .subscribe().withSubscriber(MultiAssertSubscriber.create(20))
            .assertCompletedSuccessfully()
            .assertHasNotReceivedAnyItem();

    Multi.createFrom().<Integer> emitter(emitter -> {
        IntStream.range(0, 1000).forEach(emitter::emit);
        emitter.fail(new IOException("boom"));
    }, BackPressureStrategy.DROP).subscribe()
            .withSubscriber(MultiAssertSubscriber.create())
            .request(20)
            .request(Long.MAX_VALUE)
            .assertHasFailedWith(IOException.class, "boom")
            .assertHasNotReceivedAnyItem();
}
 
Example 11
@Test
public void testThatWeCanHaveMultipleSubscribersWhenUsingBackPressure() {
    AtomicInteger count = new AtomicInteger();

    List<MultiEmitter<? super Integer>> emitters = new ArrayList<>();
    Multi<Integer> multi = Multi.createFrom().emitter(e -> {
        int i = count.incrementAndGet();
        emitters.add(e);
        e.emit(i);
        e.emit(i);
    }, BackPressureStrategy.DROP);

    MultiAssertSubscriber<Integer> subscriber1 = multi.subscribe()
            .withSubscriber(MultiAssertSubscriber.create(10))
            .assertReceived(1, 1)
            .assertNotTerminated();

    MultiAssertSubscriber<Integer> subscriber2 = multi.subscribe()
            .withSubscriber(MultiAssertSubscriber.create(10))
            .assertReceived(2, 2)
            .assertNotTerminated();

    emitters.forEach(MultiEmitter::complete);
    subscriber1.assertCompletedSuccessfully();
    subscriber2.assertCompletedSuccessfully();

}
 
Example 12
Source Project: smallrye-reactive-messaging   Source File: EmitterImpl.java    License: Apache License 2.0 5 votes vote down vote up
@SuppressWarnings("unchecked")
public EmitterImpl(EmitterConfiguration config, long defaultBufferSize) {
    this.name = config.name;
    if (defaultBufferSize <= 0) {
        throw ex.illegalArgumentForDefaultBuffer();
    }

    Consumer<MultiEmitter<? super Message<? extends T>>> deferred = fe -> {
        MultiEmitter<? super Message<? extends T>> previous = internal.getAndSet(fe);
        if (previous != null) {
            previous.complete();
        }
    };

    Multi<Message<? extends T>> tempPublisher;
    if (config.overflowBufferStrategy == null) {
        Multi<Message<? extends T>> multi = Multi.createFrom().emitter(deferred, BackPressureStrategy.BUFFER);
        tempPublisher = getPublisherUsingBufferStrategy(defaultBufferSize, multi);
    } else {
        tempPublisher = getPublisherForStrategy(config.overflowBufferStrategy, config.overflowBufferSize,
                defaultBufferSize, deferred);
    }

    if (config.broadcast) {
        publisher = (Multi<Message<? extends T>>) BroadcastHelper
                .broadcastPublisher(tempPublisher, config.numberOfSubscriberBeforeConnecting).buildRs();
    } else {
        publisher = tempPublisher;
    }
}
 
Example 13
Source Project: smallrye-reactive-messaging   Source File: EmitterImpl.java    License: Apache License 2.0 5 votes vote down vote up
Multi<Message<? extends T>> getPublisherForStrategy(OnOverflow.Strategy overFlowStrategy, long bufferSize,
        long defaultBufferSize,
        Consumer<MultiEmitter<? super Message<? extends T>>> deferred) {
    switch (overFlowStrategy) {
        case BUFFER:
            if (bufferSize > 0) {
                return ThrowingEmitter.create(deferred, bufferSize);
            } else {
                return ThrowingEmitter.create(deferred, defaultBufferSize);
            }

        case UNBOUNDED_BUFFER:
            return Multi.createFrom().emitter(deferred, BackPressureStrategy.BUFFER);

        case THROW_EXCEPTION:
            return ThrowingEmitter.create(deferred, 0);

        case DROP:
            return Multi.createFrom().emitter(deferred, BackPressureStrategy.DROP);

        case FAIL:
            return Multi.createFrom().emitter(deferred, BackPressureStrategy.ERROR);

        case LATEST:
            return Multi.createFrom().emitter(deferred, BackPressureStrategy.LATEST);

        case NONE:
            return Multi.createFrom().emitter(deferred, BackPressureStrategy.IGNORE);

        default:
            throw ex.illegalArgumentForBackPressure(overFlowStrategy);
    }
}
 
Example 14
Source Project: smallrye-mutiny   Source File: EmitterBasedMulti.java    License: Apache License 2.0 4 votes vote down vote up
public EmitterBasedMulti(Consumer<MultiEmitter<? super T>> consumer, BackPressureStrategy backpressure) {
    this.consumer = consumer;
    this.backpressure = backpressure;
}
 
Example 15
Source Project: smallrye-mutiny   Source File: EmitterBasedMultiTest.java    License: Apache License 2.0 4 votes vote down vote up
@Test(expectedExceptions = IllegalArgumentException.class)
public void testThatConsumerCannotBeNull() {
    Multi.createFrom().emitter(null, BackPressureStrategy.BUFFER);
}
 
Example 16
Source Project: smallrye-mutiny   Source File: EmitterBasedMultiTest.java    License: Apache License 2.0 4 votes vote down vote up
@Test
public void testThatEmitterCannotEmitNull() {
    AtomicBoolean terminated = new AtomicBoolean();
    Multi.createFrom().<String> emitter(e -> {
        e.onTermination(() -> terminated.set(true));
        e.emit("a");
        e.emit(null);
    }).subscribe().withSubscriber(MultiAssertSubscriber.create(2))
            .await()
            .assertHasNotCompleted()
            .assertHasFailedWith(NullPointerException.class, "")
            .assertReceived("a");
    assertThat(terminated).isTrue();

    Multi.createFrom().<String> emitter(e -> {
        e.emit("a");
        e.emit(null);
    }, BackPressureStrategy.LATEST)
            .subscribe().withSubscriber(MultiAssertSubscriber.create(2))
            .await()
            .assertHasNotCompleted()
            .assertHasFailedWith(NullPointerException.class, "")
            .assertReceived("a");

    Multi.createFrom().<String> emitter(e -> {
        e.emit("a");
        e.emit(null);
    }, BackPressureStrategy.DROP)
            .subscribe().withSubscriber(MultiAssertSubscriber.create(2))
            .await()
            .assertHasNotCompleted()
            .assertHasFailedWith(NullPointerException.class, "")
            .assertReceived("a");

    Multi.createFrom().<String> emitter(e -> {
        e.emit("a");
        e.emit(null);
    }, BackPressureStrategy.ERROR)
            .subscribe().withSubscriber(MultiAssertSubscriber.create(2))
            .await()
            .assertHasNotCompleted()
            .assertHasFailedWith(NullPointerException.class, "")
            .assertReceived("a");

    Multi.createFrom().<String> emitter(e -> {
        e.emit("a");
        e.emit(null);
    }, BackPressureStrategy.IGNORE)
            .subscribe().withSubscriber(MultiAssertSubscriber.create(2))
            .await()
            .assertHasNotCompleted()
            .assertHasFailedWith(NullPointerException.class, "")
            .assertReceived("a");

}
 
Example 17
Source Project: smallrye-mutiny   Source File: EmitterBasedMultiTest.java    License: Apache License 2.0 4 votes vote down vote up
@Test
public void testThatEmitterCannotPropagateNullAsFailure() {
    AtomicBoolean terminated = new AtomicBoolean();
    Multi.createFrom().<String> emitter(e -> {
        e.onTermination(() -> terminated.set(true));
        e.emit("a");
        e.fail(null);
    }).subscribe().withSubscriber(MultiAssertSubscriber.create(2))
            .await()
            .assertHasFailedWith(NullPointerException.class, "")
            .assertReceived("a");
    assertThat(terminated).isTrue();

    Multi.createFrom().<String> emitter(e -> {
        e.emit("a");
        e.fail(null);
    }, BackPressureStrategy.LATEST)
            .subscribe().withSubscriber(MultiAssertSubscriber.create(2))
            .await()
            .assertHasFailedWith(NullPointerException.class, "")
            .assertReceived("a");

    Multi.createFrom().<String> emitter(e -> {
        e.emit("a");
        e.fail(null);
    }, BackPressureStrategy.DROP)
            .subscribe().withSubscriber(MultiAssertSubscriber.create(2))
            .await()
            .assertHasNotCompleted()
            .assertHasFailedWith(NullPointerException.class, "")
            .assertReceived("a");

    Multi.createFrom().<String> emitter(e -> {
        e.emit("a");
        e.fail(null);
    }, BackPressureStrategy.ERROR)
            .subscribe().withSubscriber(MultiAssertSubscriber.create(2))
            .await()
            .assertHasNotCompleted()
            .assertHasFailedWith(NullPointerException.class, "")
            .assertReceived("a");

    Multi.createFrom().<String> emitter(e -> {
        e.emit("a");
        e.fail(null);
    }, BackPressureStrategy.IGNORE)
            .subscribe().withSubscriber(MultiAssertSubscriber.create(2))
            .await()
            .assertHasNotCompleted()
            .assertHasFailedWith(NullPointerException.class, "")
            .assertReceived("a");

}
 
Example 18
Source Project: quarkus   Source File: MultiRxInvokerImpl.java    License: Apache License 2.0 4 votes vote down vote up
@Override
public BackPressureStrategy getBackPressureStrategy() {
    return backpressureStrategy;
}
 
Example 19
Source Project: quarkus   Source File: MultiRxInvokerImpl.java    License: Apache License 2.0 4 votes vote down vote up
@Override
public void setBackPressureStrategy(BackPressureStrategy strategy) {
    this.backpressureStrategy = strategy;
}
 
Example 20
Source Project: smallrye-mutiny   Source File: MultiCreate.java    License: Apache License 2.0 2 votes vote down vote up
/**
 * Like {@link #emitter(Consumer, BackPressureStrategy)} with the {@link BackPressureStrategy#BUFFER} strategy.
 *
 * Note that to create hot streams, you should use a
 * {@link io.smallrye.mutiny.operators.multi.processors.BroadcastProcessor}.
 *
 * @param consumer the consumer receiving the emitter, must not be {@code null}
 * @param <T> the type of item emitted by the produced Multi
 * @return the produced {@link Multi}
 */
public <T> Multi<T> emitter(Consumer<MultiEmitter<? super T>> consumer) {
    return emitter(consumer, BackPressureStrategy.BUFFER);
}
 
Example 21
Source Project: smallrye-mutiny   Source File: MultiCreate.java    License: Apache License 2.0 2 votes vote down vote up
/**
 * Creates a {@link Multi} deferring the logic to the given consumer. The consumer can be used with callback-based
 * APIs to fire items (non-{@code null}), failure or completion events.
 * <p>
 * Emitting {@code null} value is not supported. Emitting values after having fired a failure or the completion
 * event is a no-op. So subsequent item events are dropped.
 * <p>
 * Using this method, you can produce a {@link Multi} based on listener or callbacks APIs. You register the listener
 * in the consumer and emits the items / failure / completion events when the listener is invoked. Don't forget
 * to unregister the listener on cancellation.
 * <p>
 * If the consumer throws an exception, a failure event with the exception is fired.
 *
 * Note that to create hot streams, you should use a
 * {@link io.smallrye.mutiny.operators.multi.processors.BroadcastProcessor}.
 *
 * @param consumer callback receiving the {@link MultiEmitter} and events downstream. The callback is
 *        called for each subscriber (at subscription time). Must not be {@code null}
 * @param strategy the back pressure strategy to apply when the downstream subscriber cannot keep up with the
 *        items emitted by the emitter.
 * @param <T> the type of items emitted by the emitter. Must not be {@code null}
 * @return the produced {@link Multi}
 */
public <T> Multi<T> emitter(Consumer<MultiEmitter<? super T>> consumer, BackPressureStrategy strategy) {
    Consumer<MultiEmitter<? super T>> actual = nonNull(consumer, "consumer");
    return Infrastructure.onMultiCreation(new EmitterBasedMulti<>(actual, nonNull(strategy, "strategy")));
}
 
Example 22
Source Project: quarkus   Source File: MultiRxInvoker.java    License: Apache License 2.0 votes vote down vote up
BackPressureStrategy getBackPressureStrategy(); 
Example 23
Source Project: quarkus   Source File: MultiRxInvoker.java    License: Apache License 2.0 votes vote down vote up
void setBackPressureStrategy(BackPressureStrategy strategy);