/*
* Copyright (c) 2016-2023 VMware Inc. or its affiliates, All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package reactor.core.publisher;
import java.io.File;
import java.lang.reflect.ParameterizedType;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Queue;
import java.util.Set;
import java.util.Spliterator;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;
import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.LongConsumer;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.logging.Level;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import io.micrometer.core.instrument.MeterRegistry;
import org.reactivestreams.Publisher;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;
import reactor.core.CorePublisher;
import reactor.core.CoreSubscriber;
import reactor.core.Disposable;
import reactor.core.Exceptions;
import reactor.core.Fuseable;
import reactor.core.Scannable;
import reactor.core.publisher.FluxOnAssembly.AssemblySnapshot;
import reactor.core.publisher.FluxOnAssembly.CheckpointHeavySnapshot;
import reactor.core.publisher.FluxOnAssembly.CheckpointLightSnapshot;
import reactor.core.publisher.FluxSink.OverflowStrategy;
import reactor.core.scheduler.Scheduler;
import reactor.core.scheduler.Scheduler.Worker;
import reactor.core.scheduler.Schedulers;
import reactor.util.Logger;
import reactor.util.Metrics;
import reactor.util.annotation.Nullable;
import reactor.util.concurrent.Queues;
import reactor.util.context.Context;
import reactor.util.context.ContextView;
import reactor.util.function.Tuple2;
import reactor.util.function.Tuple3;
import reactor.util.function.Tuple4;
import reactor.util.function.Tuple5;
import reactor.util.function.Tuple6;
import reactor.util.function.Tuple7;
import reactor.util.function.Tuple8;
import reactor.util.function.Tuples;
import reactor.core.observability.SignalListener;
import reactor.core.observability.SignalListenerFactory;
import reactor.util.retry.Retry;
/**
* A Reactive Streams {@link Publisher} with rx operators that emits 0 to N elements, and then completes
* (successfully or with an error).
*
* The recommended way to learn about the {@link Flux} API and discover new operators is
* through the reference documentation, rather than through this javadoc (as opposed to
* learning more about individual operators). See the
* "which operator do I need?" appendix .
*
*
*
*
*
It is intended to be used in implementations and return types. Input parameters should keep using raw
* {@link Publisher} as much as possible.
*
*
If it is known that the underlying {@link Publisher} will emit 0 or 1 element, {@link Mono} should be used
* instead.
*
*
Note that using state in the {@code java.util.function} / lambdas used within Flux operators
* should be avoided, as these may be shared between several {@link Subscriber Subscribers}.
*
*
{@link #subscribe(CoreSubscriber)} is an internal extension to
* {@link #subscribe(Subscriber)} used internally for {@link Context} passing. User
* provided {@link Subscriber} may
* be passed to this "subscribe" extension but will loose the available
* per-subscribe {@link Hooks#onLastOperator}.
*
* @param the element type of this Reactive Streams {@link Publisher}
*
* @author Sebastien Deleuze
* @author Stephane Maldini
* @author David Karnok
* @author Simon Baslé
*
* @see Mono
*/
public abstract class Flux implements CorePublisher {
// ==============================================================================================================
// Static Generators
// ==============================================================================================================
/**
* Build a {@link Flux} whose data are generated by the combination of the
* most recently published value from each of the {@link Publisher} sources.
*
*
*
*
Discard Support: This operator is NOT suited for types that need guaranteed discard of unpropagated elements, as
* it doesn't track which elements have been used by the combinator and which haven't. Furthermore, elements can and
* will be passed to the combinator multiple times.
*
* @param sources The {@link Publisher} sources to combine values from
* @param combinator The aggregate function that will receive the latest value from each upstream and return the value
* to signal downstream
* @param type of the value from sources
* @param The produced output after transformation by the given combinator
*
* @return a {@link Flux} based on the produced combinations
*/
@SafeVarargs
public static Flux combineLatest(Function combinator, Publisher extends T>... sources) {
return combineLatest(combinator, Queues.XS_BUFFER_SIZE, sources);
}
/**
* Build a {@link Flux} whose data are generated by the combination of the
* most recently published value from each of the {@link Publisher} sources.
*
*
*
*
Discard Support: This operator is NOT suited for types that need guaranteed discard of unpropagated elements, as
* it doesn't track which elements have been used by the combinator and which haven't. Furthermore, elements can and
* will be passed to the combinator multiple times.
*
* @param sources The {@link Publisher} sources to combine values from
* @param prefetch The demand sent to each combined source {@link Publisher}
* @param combinator The aggregate function that will receive the latest value from each upstream and return the value
* to signal downstream
* @param type of the value from sources
* @param The produced output after transformation by the given combinator
*
* @return a {@link Flux} based on the produced combinations
*/
@SafeVarargs
public static Flux combineLatest(Function combinator, int prefetch,
Publisher extends T>... sources) {
if (sources.length == 0) {
return empty();
}
if (sources.length == 1) {
Publisher extends T> source = sources[0];
if (source instanceof Fuseable) {
return onAssembly(new FluxMapFuseable<>(from(source),
v -> combinator.apply(new Object[]{v})));
}
return onAssembly(new FluxMap<>(from(source),
v -> combinator.apply(new Object[]{v})));
}
return onAssembly(new FluxCombineLatest<>(sources,
combinator, Queues.get(prefetch), prefetch));
}
/**
* Build a {@link Flux} whose data are generated by the combination of the
* most recently published value from each of two {@link Publisher} sources.
*
*
*
*
Discard Support: This operator is NOT suited for types that need guaranteed discard of unpropagated elements, as
* it doesn't track which elements have been used by the combinator and which haven't. Furthermore, elements can and
* will be passed to the combinator multiple times.
*
* @param source1 The first {@link Publisher} source to combine values from
* @param source2 The second {@link Publisher} source to combine values from
* @param combinator The aggregate function that will receive the latest value from each upstream and return the value
* to signal downstream
* @param type of the value from source1
* @param type of the value from source2
* @param The produced output after transformation by the given combinator
*
* @return a {@link Flux} based on the produced combinations
*/
@SuppressWarnings("unchecked")
public static Flux combineLatest(Publisher extends T1> source1,
Publisher extends T2> source2,
BiFunction super T1, ? super T2, ? extends V> combinator) {
return combineLatest(tuple -> combinator.apply((T1)tuple[0], (T2)tuple[1]), source1, source2);
}
/**
* Build a {@link Flux} whose data are generated by the combination of the
* most recently published value from each of three {@link Publisher} sources.
*
*
*
*
Discard Support: This operator is NOT suited for types that need guaranteed discard of unpropagated elements, as
* it doesn't track which elements have been used by the combinator and which haven't. Furthermore, elements can and
* will be passed to the combinator multiple times.
*
* @param source1 The first {@link Publisher} source to combine values from
* @param source2 The second {@link Publisher} source to combine values from
* @param source3 The third {@link Publisher} source to combine values from
* @param combinator The aggregate function that will receive the latest value from each upstream and return the value
* to signal downstream
* @param type of the value from source1
* @param type of the value from source2
* @param type of the value from source3
* @param The produced output after transformation by the given combinator
*
* @return a {@link Flux} based on the produced combinations
*/
public static Flux combineLatest(Publisher extends T1> source1,
Publisher extends T2> source2,
Publisher extends T3> source3,
Function combinator) {
return combineLatest(combinator, source1, source2, source3);
}
/**
* Build a {@link Flux} whose data are generated by the combination of the
* most recently published value from each of four {@link Publisher} sources.
*
*
*
*
Discard Support: This operator is NOT suited for types that need guaranteed discard of unpropagated elements, as
* it doesn't track which elements have been used by the combinator and which haven't. Furthermore, elements can and
* will be passed to the combinator multiple times.
*
* @param source1 The first {@link Publisher} source to combine values from
* @param source2 The second {@link Publisher} source to combine values from
* @param source3 The third {@link Publisher} source to combine values from
* @param source4 The fourth {@link Publisher} source to combine values from
* @param combinator The aggregate function that will receive the latest value from each upstream and return the value
* to signal downstream
* @param type of the value from source1
* @param type of the value from source2
* @param type of the value from source3
* @param type of the value from source4
* @param The produced output after transformation by the given combinator
*
* @return a {@link Flux} based on the produced combinations
*/
public static Flux combineLatest(Publisher extends T1> source1,
Publisher extends T2> source2,
Publisher extends T3> source3,
Publisher extends T4> source4,
Function combinator) {
return combineLatest(combinator, source1, source2, source3, source4);
}
/**
* Build a {@link Flux} whose data are generated by the combination of the
* most recently published value from each of five {@link Publisher} sources.
*
*
*
*
Discard Support: This operator is NOT suited for types that need guaranteed discard of unpropagated elements, as
* it doesn't track which elements have been used by the combinator and which haven't. Furthermore, elements can and
* will be passed to the combinator multiple times.
*
* @param source1 The first {@link Publisher} source to combine values from
* @param source2 The second {@link Publisher} source to combine values from
* @param source3 The third {@link Publisher} source to combine values from
* @param source4 The fourth {@link Publisher} source to combine values from
* @param source5 The fifth {@link Publisher} source to combine values from
* @param combinator The aggregate function that will receive the latest value from each upstream and return the value
* to signal downstream
* @param type of the value from source1
* @param type of the value from source2
* @param type of the value from source3
* @param type of the value from source4
* @param type of the value from source5
* @param The produced output after transformation by the given combinator
*
* @return a {@link Flux} based on the produced combinations
*/
public static Flux combineLatest(Publisher extends T1> source1,
Publisher extends T2> source2,
Publisher extends T3> source3,
Publisher extends T4> source4,
Publisher extends T5> source5,
Function combinator) {
return combineLatest(combinator, source1, source2, source3, source4, source5);
}
/**
* Build a {@link Flux} whose data are generated by the combination of the
* most recently published value from each of six {@link Publisher} sources.
*
*
*
*
Discard Support: This operator is NOT suited for types that need guaranteed discard of unpropagated elements, as
* it doesn't track which elements have been used by the combinator and which haven't. Furthermore, elements can and
* will be passed to the combinator multiple times.
*
* @param source1 The first {@link Publisher} source to combine values from
* @param source2 The second {@link Publisher} source to combine values from
* @param source3 The third {@link Publisher} source to combine values from
* @param source4 The fourth {@link Publisher} source to combine values from
* @param source5 The fifth {@link Publisher} source to combine values from
* @param source6 The sixth {@link Publisher} source to combine values from
* @param combinator The aggregate function that will receive the latest value from each upstream and return the value
* to signal downstream
* @param type of the value from source1
* @param type of the value from source2
* @param type of the value from source3
* @param type of the value from source4
* @param type of the value from source5
* @param type of the value from source6
* @param The produced output after transformation by the given combinator
*
* @return a {@link Flux} based on the produced combinations
*/
public static Flux combineLatest(Publisher extends T1> source1,
Publisher extends T2> source2,
Publisher extends T3> source3,
Publisher extends T4> source4,
Publisher extends T5> source5,
Publisher extends T6> source6,
Function combinator) {
return combineLatest(combinator, source1, source2, source3, source4, source5, source6);
}
/**
* Build a {@link Flux} whose data are generated by the combination of the
* most recently published value from each
* of the {@link Publisher} sources provided in an {@link Iterable}.
*
*
*
*
Discard Support: This operator is NOT suited for types that need guaranteed discard of unpropagated elements, as
* it doesn't track which elements have been used by the combinator and which haven't. Furthermore, elements can and
* will be passed to the combinator multiple times.
*
* @param sources The list of {@link Publisher} sources to combine values from
* @param combinator The aggregate function that will receive the latest value from each upstream and return the value
* to signal downstream
* @param The common base type of the values from sources
* @param The produced output after transformation by the given combinator
*
* @return a {@link Flux} based on the produced combinations
*/
public static Flux combineLatest(Iterable extends Publisher extends T>> sources,
Function combinator) {
return combineLatest(sources, Queues.XS_BUFFER_SIZE, combinator);
}
/**
* Build a {@link Flux} whose data are generated by the combination of the
* most recently published value from each
* of the {@link Publisher} sources provided in an {@link Iterable}.
*
*
*
*
Discard Support: This operator is NOT suited for types that need guaranteed discard of unpropagated elements, as
* it doesn't track which elements have been used by the combinator and which haven't. Furthermore, elements can and
* will be passed to the combinator multiple times.
*
* @param sources The list of {@link Publisher} sources to combine values from
* @param prefetch demand produced to each combined source {@link Publisher}
* @param combinator The aggregate function that will receive the latest value from each upstream and return the value
* to signal downstream
* @param The common base type of the values from sources
* @param The produced output after transformation by the given combinator
*
* @return a {@link Flux} based on the produced combinations
*/
public static Flux combineLatest(Iterable extends Publisher extends T>> sources,
int prefetch,
Function combinator) {
return onAssembly(new FluxCombineLatest<>(sources,
combinator,
Queues.get(prefetch), prefetch));
}
/**
* Concatenate all sources provided in an {@link Iterable}, forwarding elements
* emitted by the sources downstream.
*
* Concatenation is achieved by sequentially subscribing to the first source then
* waiting for it to complete before subscribing to the next, and so on until the
* last source completes. Any error interrupts the sequence immediately and is
* forwarded downstream.
*
*
*
* @param sources The {@link Iterable} of {@link Publisher} to concatenate
* @param The type of values in both source and output sequences
*
* @return a new {@link Flux} concatenating all source sequences
*/
public static Flux concat(Iterable extends Publisher extends T>> sources) {
return onAssembly(new FluxConcatIterable<>(sources));
}
/**
* Concatenates the values to the end of the {@link Flux}
*
*
*
* @param values The values to concatenate
*
* @return a new {@link Flux} concatenating all source sequences
*/
@SafeVarargs
public final Flux concatWithValues(T... values) {
return concatWith(Flux.fromArray(values));
}
/**
* Concatenate all sources emitted as an onNext signal from a parent {@link Publisher},
* forwarding elements emitted by the sources downstream.
*
* Concatenation is achieved by sequentially subscribing to the first source then
* waiting for it to complete before subscribing to the next, and so on until the
* last source completes. Any error interrupts the sequence immediately and is
* forwarded downstream.
*
*
*
*
Discard Support: This operator discards elements it internally queued for backpressure upon cancellation.
*
* @param sources The {@link Publisher} of {@link Publisher} to concatenate
* @param The type of values in both source and output sequences
*
* @return a new {@link Flux} concatenating all inner sources sequences
*/
public static Flux concat(Publisher extends Publisher extends T>> sources) {
return concat(sources, Queues.XS_BUFFER_SIZE);
}
/**
* Concatenate all sources emitted as an onNext signal from a parent {@link Publisher},
* forwarding elements emitted by the sources downstream.
*
* Concatenation is achieved by sequentially subscribing to the first source then
* waiting for it to complete before subscribing to the next, and so on until the
* last source completes. Any error interrupts the sequence immediately and is
* forwarded downstream.
*
*
*
*
Discard Support: This operator discards elements it internally queued for backpressure upon cancellation.
*
* @param sources The {@link Publisher} of {@link Publisher} to concatenate
* @param prefetch the number of Publishers to prefetch from the outer {@link Publisher}
* @param The type of values in both source and output sequences
*
* @return a new {@link Flux} concatenating all inner sources sequences
*/
public static Flux concat(Publisher extends Publisher extends T>> sources, int prefetch) {
return from(sources).concatMap(identityFunction(), prefetch);
}
/**
* Concatenate all sources provided as a vararg, forwarding elements emitted by the
* sources downstream.
*
* Concatenation is achieved by sequentially subscribing to the first source then
* waiting for it to complete before subscribing to the next, and so on until the
* last source completes. Any error interrupts the sequence immediately and is
* forwarded downstream.
*
*
*
* @param sources The {@link Publisher} of {@link Publisher} to concat
* @param The type of values in both source and output sequences
*
* @return a new {@link Flux} concatenating all source sequences
*/
@SafeVarargs
public static Flux concat(Publisher extends T>... sources) {
return onAssembly(new FluxConcatArray<>(false, sources));
}
/**
* Concatenate all sources emitted as an onNext signal from a parent {@link Publisher},
* forwarding elements emitted by the sources downstream.
*
* Concatenation is achieved by sequentially subscribing to the first source then
* waiting for it to complete before subscribing to the next, and so on until the
* last source completes. Errors do not interrupt the main sequence but are propagated
* after the rest of the sources have had a chance to be concatenated.
*
*
*
*
*
Discard Support: This operator discards elements it internally queued for backpressure upon cancellation.
*
* @param sources The {@link Publisher} of {@link Publisher} to concatenate
* @param The type of values in both source and output sequences
*
* @return a new {@link Flux} concatenating all inner sources sequences, delaying errors
*/
public static Flux concatDelayError(Publisher extends Publisher extends T>> sources) {
return concatDelayError(sources, Queues.XS_BUFFER_SIZE);
}
/**
* Concatenate all sources emitted as an onNext signal from a parent {@link Publisher},
* forwarding elements emitted by the sources downstream.
*
* Concatenation is achieved by sequentially subscribing to the first source then
* waiting for it to complete before subscribing to the next, and so on until the
* last source completes. Errors do not interrupt the main sequence but are propagated
* after the rest of the sources have had a chance to be concatenated.
*
*
*
*
Discard Support: This operator discards elements it internally queued for backpressure upon cancellation.
*
* @param sources The {@link Publisher} of {@link Publisher} to concatenate
* @param prefetch number of elements to prefetch from the source, to be turned into inner Publishers
* @param The type of values in both source and output sequences
*
* @return a new {@link Flux} concatenating all inner sources sequences until complete or error
*/
public static Flux concatDelayError(Publisher extends Publisher extends T>> sources, int prefetch) {
return from(sources).concatMapDelayError(identityFunction(), prefetch);
}
/**
* Concatenate all sources emitted as an onNext signal from a parent {@link Publisher},
* forwarding elements emitted by the sources downstream.
*
* Concatenation is achieved by sequentially subscribing to the first source then
* waiting for it to complete before subscribing to the next, and so on until the
* last source completes.
*
* Errors do not interrupt the main sequence but are propagated after the current
* concat backlog if {@code delayUntilEnd} is {@literal false} or after all sources
* have had a chance to be concatenated if {@code delayUntilEnd} is {@literal true}.
*
*
*
*
*
Discard Support: This operator discards elements it internally queued for backpressure upon cancellation.
*
* @param sources The {@link Publisher} of {@link Publisher} to concatenate
* @param delayUntilEnd delay error until all sources have been consumed instead of
* after the current source
* @param prefetch the number of Publishers to prefetch from the outer {@link Publisher}
* @param The type of values in both source and output sequences
*
* @return a new {@link Flux} concatenating all inner sources sequences until complete or error
*/
public static Flux concatDelayError(Publisher extends Publisher extends
T>> sources, boolean delayUntilEnd, int prefetch) {
return from(sources).concatMapDelayError(identityFunction(), delayUntilEnd, prefetch);
}
/**
* Concatenate all sources provided as a vararg, forwarding elements emitted by the
* sources downstream.
*
* Concatenation is achieved by sequentially subscribing to the first source then
* waiting for it to complete before subscribing to the next, and so on until the
* last source completes. Errors do not interrupt the main sequence but are propagated
* after the rest of the sources have had a chance to be concatenated.
*
*
*
*
*
Discard Support: This operator discards elements it internally queued for backpressure upon cancellation.
*
* @param sources The {@link Publisher} of {@link Publisher} to concat
* @param The type of values in both source and output sequences
*
* @return a new {@link Flux} concatenating all source sequences
*/
@SafeVarargs
public static Flux concatDelayError(Publisher extends T>... sources) {
return onAssembly(new FluxConcatArray<>(true, sources));
}
/**
* Programmatically create a {@link Flux} with the capability of emitting multiple
* elements in a synchronous or asynchronous manner through the {@link FluxSink} API.
* This includes emitting elements from multiple threads.
*
*
*
* This Flux factory is useful if one wants to adapt some other multi-valued async API
* and not worry about cancellation and backpressure (which is handled by buffering
* all signals if the downstream can't keep up).
*
* For example:
*
*
* Flux.<String>create(emitter -> {
*
* ActionListener al = e -> {
* emitter.next(textField.getText());
* };
* // without cleanup support:
*
* button.addActionListener(al);
*
* // with cleanup support:
*
* button.addActionListener(al);
* emitter.onDispose(() -> {
* button.removeListener(al);
* });
* });
*
*
* Discard Support: The {@link FluxSink} exposed by this operator buffers in case of
* overflow. The buffer is discarded when the main sequence is cancelled.
*
* @param The type of values in the sequence
* @param emitter Consume the {@link FluxSink} provided per-subscriber by Reactor to generate signals.
* @return a {@link Flux}
* @see #push(Consumer)
*/
public static Flux create(Consumer super FluxSink> emitter) {
return create(emitter, OverflowStrategy.BUFFER);
}
/**
* Programmatically create a {@link Flux} with the capability of emitting multiple
* elements in a synchronous or asynchronous manner through the {@link FluxSink} API.
* This includes emitting elements from multiple threads.
*
*
*
* This Flux factory is useful if one wants to adapt some other multi-valued async API
* and not worry about cancellation and backpressure (which is handled by buffering
* all signals if the downstream can't keep up).
*
* For example:
*
*
* Flux.<String>create(emitter -> {
*
* ActionListener al = e -> {
* emitter.next(textField.getText());
* };
* // without cleanup support:
*
* button.addActionListener(al);
*
* // with cleanup support:
*
* button.addActionListener(al);
* emitter.onDispose(() -> {
* button.removeListener(al);
* });
* }, FluxSink.OverflowStrategy.LATEST);
*
*
* Discard Support: The {@link FluxSink} exposed by this operator discards elements
* as relevant to the chosen {@link OverflowStrategy}. For example, the {@link OverflowStrategy#DROP}
* discards each items as they are being dropped, while {@link OverflowStrategy#BUFFER}
* will discard the buffer upon cancellation.
*
* @param The type of values in the sequence
* @param backpressure the backpressure mode, see {@link OverflowStrategy} for the
* available backpressure modes
* @param emitter Consume the {@link FluxSink} provided per-subscriber by Reactor to generate signals.
* @return a {@link Flux}
* @see #push(Consumer, reactor.core.publisher.FluxSink.OverflowStrategy)
*/
public static Flux create(Consumer super FluxSink> emitter, OverflowStrategy backpressure) {
return onAssembly(new FluxCreate<>(emitter, backpressure, FluxCreate.CreateMode.PUSH_PULL));
}
/**
* Programmatically create a {@link Flux} with the capability of emitting multiple
* elements from a single-threaded producer through the {@link FluxSink} API. For
* a multi-threaded capable alternative, see {@link #create(Consumer)}.
*
*
*
* This Flux factory is useful if one wants to adapt some other single-threaded
* multi-valued async API and not worry about cancellation and backpressure (which is
* handled by buffering all signals if the downstream can't keep up).
*
* For example:
*
*
* Flux.<String>push(emitter -> {
*
* ActionListener al = e -> {
* emitter.next(textField.getText());
* };
* // without cleanup support:
*
* button.addActionListener(al);
*
* // with cleanup support:
*
* button.addActionListener(al);
* emitter.onDispose(() -> {
* button.removeListener(al);
* });
* });
*
*
* Discard Support: The {@link FluxSink} exposed by this operator buffers in case of
* overflow. The buffer is discarded when the main sequence is cancelled.
*
* @param The type of values in the sequence
* @param emitter Consume the {@link FluxSink} provided per-subscriber by Reactor to generate signals.
* @return a {@link Flux}
* @see #create(Consumer)
*/
public static Flux push(Consumer super FluxSink> emitter) {
return push(emitter, OverflowStrategy.BUFFER);
}
/**
* Programmatically create a {@link Flux} with the capability of emitting multiple
* elements from a single-threaded producer through the {@link FluxSink} API. For
* a multi-threaded capable alternative, see {@link #create(Consumer, reactor.core.publisher.FluxSink.OverflowStrategy)}.
*
*
*
* This Flux factory is useful if one wants to adapt some other single-threaded
* multi-valued async API and not worry about cancellation and backpressure (which is
* handled by buffering all signals if the downstream can't keep up).
*
* For example:
*
*
* Flux.<String>push(emitter -> {
*
* ActionListener al = e -> {
* emitter.next(textField.getText());
* };
* // without cleanup support:
*
* button.addActionListener(al);
*
* // with cleanup support:
*
* button.addActionListener(al);
* emitter.onDispose(() -> {
* button.removeListener(al);
* });
* }, FluxSink.OverflowStrategy.LATEST);
*
*
* Discard Support: The {@link FluxSink} exposed by this operator discards elements
* as relevant to the chosen {@link OverflowStrategy}. For example, the {@link OverflowStrategy#DROP}
* discards each items as they are being dropped, while {@link OverflowStrategy#BUFFER}
* will discard the buffer upon cancellation.
*
* @param The type of values in the sequence
* @param backpressure the backpressure mode, see {@link OverflowStrategy} for the
* available backpressure modes
* @param emitter Consume the {@link FluxSink} provided per-subscriber by Reactor to generate signals.
* @return a {@link Flux}
* @see #create(Consumer, reactor.core.publisher.FluxSink.OverflowStrategy)
*/
public static Flux push(Consumer super FluxSink> emitter, OverflowStrategy backpressure) {
return onAssembly(new FluxCreate<>(emitter, backpressure, FluxCreate.CreateMode.PUSH_ONLY));
}
/**
* Lazily supply a {@link Publisher} every time a {@link Subscription} is made on the
* resulting {@link Flux}, so the actual source instantiation is deferred until each
* subscribe and the {@link Supplier} can create a subscriber-specific instance.
* If the supplier doesn't generate a new instance however, this operator will
* effectively behave like {@link #from(Publisher)}.
*
*
*
*
* @param supplier the {@link Publisher} {@link Supplier} to call on subscribe
* @param the type of values passing through the {@link Flux}
*
* @return a deferred {@link Flux}
* @see #deferContextual(Function)
*/
public static Flux defer(Supplier extends Publisher> supplier) {
return onAssembly(new FluxDefer<>(supplier));
}
/**
* Lazily supply a {@link Publisher} every time a {@link Subscription} is made on the
* resulting {@link Flux}, so the actual source instantiation is deferred until each
* subscribe and the {@link Function} can create a subscriber-specific instance.
* This operator behaves the same way as {@link #defer(Supplier)},
* but accepts a {@link Function} that will receive the current {@link ContextView} as an argument.
* If the function doesn't generate a new instance however, this operator will
* effectively behave like {@link #from(Publisher)}.
*
*
*
*
* @param contextualPublisherFactory the {@link Publisher} {@link Function} to call on subscribe
* @param the type of values passing through the {@link Flux}
* @return a deferred {@link Flux} deriving actual {@link Flux} from context values for each subscription
*/
public static Flux deferContextual(Function> contextualPublisherFactory) {
return onAssembly(new FluxDeferContextual<>(contextualPublisherFactory));
}
/**
* Create a {@link Flux} that completes without emitting any item.
*
*
*
* @param the reified type of the target {@link Subscriber}
*
* @return an empty {@link Flux}
*/
public static Flux empty() {
return FluxEmpty.instance();
}
/**
* Create a {@link Flux} that terminates with the specified error immediately after
* being subscribed to.
*
*
*
* @param error the error to signal to each {@link Subscriber}
* @param the reified type of the target {@link Subscriber}
*
* @return a new failing {@link Flux}
*/
public static Flux error(Throwable error) {
return error(error, false);
}
/**
* Create a {@link Flux} that terminates with an error immediately after being
* subscribed to. The {@link Throwable} is generated by a {@link Supplier}, invoked
* each time there is a subscription and allowing for lazy instantiation.
*
*
*
* @param errorSupplier the error signal {@link Supplier} to invoke for each {@link Subscriber}
* @param the reified type of the target {@link Subscriber}
*
* @return a new failing {@link Flux}
*/
public static Flux error(Supplier extends Throwable> errorSupplier) {
return onAssembly(new FluxErrorSupplied<>(errorSupplier));
}
/**
* Create a {@link Flux} that terminates with the specified error, either immediately
* after being subscribed to or after being first requested.
*
*
*
*
* @param throwable the error to signal to each {@link Subscriber}
* @param whenRequested if true, will onError on the first request instead of subscribe().
* @param the reified type of the target {@link Subscriber}
*
* @return a new failing {@link Flux}
*/
public static Flux error(Throwable throwable, boolean whenRequested) {
if (whenRequested) {
return onAssembly(new FluxErrorOnRequest<>(throwable));
}
else {
return onAssembly(new FluxError<>(throwable));
}
}
/**
* Pick the first {@link Publisher} to emit any signal (onNext/onError/onComplete) and
* replay all signals from that {@link Publisher}, effectively behaving like the
* fastest of these competing sources.
*
*
*
*
* @param sources The competing source publishers
* @param The type of values in both source and output sequences
*
* @return a new {@link Flux} behaving like the fastest of its sources
* @deprecated use {@link #firstWithSignal(Publisher[])}. To be removed in reactor 3.5.
*/
@SafeVarargs
@Deprecated
public static Flux first(Publisher extends I>... sources) {
return firstWithSignal(sources);
}
/**
* Pick the first {@link Publisher} to emit any signal (onNext/onError/onComplete) and
* replay all signals from that {@link Publisher}, effectively behaving like the
* fastest of these competing sources.
*
*
*
*
* @param sources The competing source publishers
* @param The type of values in both source and output sequences
*
* @return a new {@link Flux} behaving like the fastest of its sources
* @deprecated use {@link #firstWithSignal(Iterable)}. To be removed in reactor 3.5.
*/
@Deprecated
public static Flux first(Iterable extends Publisher extends I>> sources) {
return firstWithSignal(sources);
}
/**
* Pick the first {@link Publisher} to emit any signal (onNext/onError/onComplete) and
* replay all signals from that {@link Publisher}, effectively behaving like the
* fastest of these competing sources.
*
*
*
*
* @param sources The competing source publishers
* @param The type of values in both source and output sequences
*
* @return a new {@link Flux} behaving like the fastest of its sources
*/
@SafeVarargs
public static Flux firstWithSignal(Publisher extends I>... sources) {
return onAssembly(new FluxFirstWithSignal<>(sources));
}
/**
* Pick the first {@link Publisher} to emit any signal (onNext/onError/onComplete) and
* replay all signals from that {@link Publisher}, effectively behaving like the
* fastest of these competing sources.
*
*
*
*
* @param sources The competing source publishers
* @param The type of values in both source and output sequences
*
* @return a new {@link Flux} behaving like the fastest of its sources
*/
public static Flux firstWithSignal(Iterable extends Publisher extends I>> sources) {
return onAssembly(new FluxFirstWithSignal<>(sources));
}
/**
* Pick the first {@link Publisher} to emit any value and replay all values
* from that {@link Publisher}, effectively behaving like the source that first
* emits an {@link Subscriber#onNext(Object) onNext}.
*
*
* Sources with values always "win" over empty sources (ones that only emit onComplete)
* or failing sources (ones that only emit onError).
*
* When no source can provide a value, this operator fails with a {@link NoSuchElementException}
* (provided there are at least two sources). This exception has a {@link Exceptions#multiple(Throwable...) composite}
* as its {@link Throwable#getCause() cause} that can be used to inspect what went wrong with each source
* (so the composite has as many elements as there are sources).
*
* Exceptions from failing sources are directly reflected in the composite at the index of the failing source.
* For empty sources, a {@link NoSuchElementException} is added at their respective index.
* One can use {@link Exceptions#unwrapMultiple(Throwable) Exceptions.unwrapMultiple(topLevel.getCause())}
* to easily inspect these errors as a {@link List}.
*
* Note that like in {@link #firstWithSignal(Iterable)}, an infinite source can be problematic
* if no other source emits onNext.
*
*
*
* @param sources An {@link Iterable} of the competing source publishers
* @param The type of values in both source and output sequences
*
* @return a new {@link Flux} behaving like the fastest of its sources
*/
public static Flux firstWithValue(Iterable extends Publisher extends I>> sources) {
return onAssembly(new FluxFirstWithValue<>(sources));
}
/**
* Pick the first {@link Publisher} to emit any value and replay all values
* from that {@link Publisher}, effectively behaving like the source that first
* emits an {@link Subscriber#onNext(Object) onNext}.
*
* Sources with values always "win" over an empty source (ones that only emit onComplete)
* or failing sources (ones that only emit onError).
*
* When no source can provide a value, this operator fails with a {@link NoSuchElementException}
* (provided there are at least two sources). This exception has a {@link Exceptions#multiple(Throwable...) composite}
* as its {@link Throwable#getCause() cause} that can be used to inspect what went wrong with each source
* (so the composite has as many elements as there are sources).
*
* Exceptions from failing sources are directly reflected in the composite at the index of the failing source.
* For empty sources, a {@link NoSuchElementException} is added at their respective index.
* One can use {@link Exceptions#unwrapMultiple(Throwable) Exceptions.unwrapMultiple(topLevel.getCause())}
* to easily inspect these errors as a {@link List}.
*
* Note that like in {@link #firstWithSignal(Publisher[])}, an infinite source can be problematic
* if no other source emits onNext.
* In case the {@code first} source is already an array-based {@link #firstWithValue(Publisher, Publisher[])}
* instance, nesting is avoided: a single new array-based instance is created with all the
* sources from {@code first} plus all the {@code others} sources at the same level.
*
*
*
* @param first The first competing source publisher
* @param others The other competing source publishers
* @param The type of values in both source and output sequences
*
* @return a new {@link Flux} behaving like the fastest of its sources
*/
@SafeVarargs
public static Flux firstWithValue(Publisher extends I> first, Publisher extends I>... others) {
if (first instanceof FluxFirstWithValue) {
@SuppressWarnings("unchecked")
FluxFirstWithValue orPublisher = (FluxFirstWithValue) first;
FluxFirstWithValue result = orPublisher.firstValuedAdditionalSources(others);
if (result != null) {
return result;
}
}
return onAssembly(new FluxFirstWithValue<>(first, others));
}
/**
* Decorate the specified {@link Publisher} with the {@link Flux} API.
*
*
*
* {@link Hooks#onEachOperator(String, Function)} and similar assembly hooks are applied
* unless the source is already a {@link Flux}.
*
* @param source the source to decorate
* @param The type of values in both source and output sequences
*
* @return a new {@link Flux}
*/
public static Flux from(Publisher extends T> source) {
//duplicated in wrap, but necessary to detect early and thus avoid applying assembly
if (source instanceof Flux && !ContextPropagationSupport.shouldWrapPublisher(source)) {
@SuppressWarnings("unchecked")
Flux casted = (Flux) source;
return casted;
}
//all other cases (including ScalarCallable) are managed without assembly in wrap
//let onAssembly point to Flux.from:
return onAssembly(wrap(source));
}
/**
* Create a {@link Flux} that emits the items contained in the provided array.
*
*
*
* @param array the array to read data from
* @param The type of values in the source array and resulting Flux
*
* @return a new {@link Flux}
*/
public static Flux fromArray(T[] array) {
if (array.length == 0) {
return empty();
}
if (array.length == 1) {
return just(array[0]);
}
return onAssembly(new FluxArray<>(array));
}
/**
* Create a {@link Flux} that emits the items contained in the provided {@link Iterable}.
* The {@link Iterable#iterator()} method will be invoked at least once and at most twice
* for each subscriber.
*
*
*
* This operator inspects the {@link Iterable}'s {@link Spliterator} to assess if the iteration
* can be guaranteed to be finite (see {@link Operators#onDiscardMultiple(Iterator, boolean, Context)}).
* Since the default Spliterator wraps the Iterator we can have two {@link Iterable#iterator()}
* calls. This second invocation is skipped on a {@link Collection} however, a type which is
* assumed to be always finite.
*
*
Discard Support: Upon cancellation, this operator attempts to discard the remainder of the
* {@link Iterable} if it can safely ensure the iterator is finite.
* Note that this means the {@link Iterable#iterator()} method could be invoked twice.
*
* @param it the {@link Iterable} to read data from
* @param The type of values in the source {@link Iterable} and resulting Flux
*
* @return a new {@link Flux}
*/
public static Flux fromIterable(Iterable extends T> it) {
return onAssembly(new FluxIterable<>(it));
}
/**
* Create a {@link Flux} that emits the items contained in the provided {@link Stream}.
* Keep in mind that a {@link Stream} cannot be re-used, which can be problematic in
* case of multiple subscriptions or re-subscription (like with {@link #repeat()} or
* {@link #retry()}). The {@link Stream} is {@link Stream#close() closed} automatically
* by the operator on cancellation, error or completion.
*
*
*
*
Discard Support: Upon cancellation, this operator attempts to discard remainder of the
* {@link Stream} through its open {@link Spliterator}, if it can safely ensure it is finite
* (see {@link Operators#onDiscardMultiple(Iterator, boolean, Context)}).
*
* @param s the {@link Stream} to read data from
* @param The type of values in the source {@link Stream} and resulting Flux
*
* @return a new {@link Flux}
*/
public static Flux fromStream(Stream extends T> s) {
Objects.requireNonNull(s, "Stream s must be provided");
return onAssembly(new FluxStream<>(() -> s));
}
/**
* Create a {@link Flux} that emits the items contained in a {@link Stream} created by
* the provided {@link Supplier} for each subscription. The {@link Stream} is
* {@link Stream#close() closed} automatically by the operator on cancellation, error
* or completion.
*
*
*
*
Discard Support: Upon cancellation, this operator attempts to discard remainder of the
* {@link Stream} through its open {@link Spliterator}, if it can safely ensure it is finite
* (see {@link Operators#onDiscardMultiple(Iterator, boolean, Context)}).
*
* @param streamSupplier the {@link Supplier} that generates the {@link Stream} from
* which to read data
* @param The type of values in the source {@link Stream} and resulting Flux
*
* @return a new {@link Flux}
*/
public static Flux fromStream(Supplier> streamSupplier) {
return onAssembly(new FluxStream<>(streamSupplier));
}
/**
* Programmatically create a {@link Flux} by generating signals one-by-one via a
* consumer callback.
*
*
*
* @param the value type emitted
* @param generator Consume the {@link SynchronousSink} provided per-subscriber by Reactor
* to generate a single signal on each pass.
*
* @return a {@link Flux}
*/
public static Flux generate(Consumer> generator) {
Objects.requireNonNull(generator, "generator");
return onAssembly(new FluxGenerate<>(generator));
}
/**
* Programmatically create a {@link Flux} by generating signals one-by-one via a
* consumer callback and some state. The {@code stateSupplier} may return {@literal null}.
*
*
*
* @param the value type emitted
* @param the per-subscriber custom state type
* @param stateSupplier called for each incoming Subscriber to provide the initial state for the generator bifunction
* @param generator Consume the {@link SynchronousSink} provided per-subscriber by Reactor
* as well as the current state to generate a single signal on each pass
* and return a (new) state.
* @return a {@link Flux}
*/
public static Flux generate(Callable stateSupplier, BiFunction, S> generator) {
return onAssembly(new FluxGenerate<>(stateSupplier, generator));
}
/**
* Programmatically create a {@link Flux} by generating signals one-by-one via a
* consumer callback and some state, with a final cleanup callback. The
* {@code stateSupplier} may return {@literal null} but your cleanup {@code stateConsumer}
* will need to handle the null case.
*
*
*
* @param the value type emitted
* @param the per-subscriber custom state type
* @param stateSupplier called for each incoming Subscriber to provide the initial state for the generator bifunction
* @param generator Consume the {@link SynchronousSink} provided per-subscriber by Reactor
* as well as the current state to generate a single signal on each pass
* and return a (new) state.
* @param stateConsumer called after the generator has terminated or the downstream cancelled, receiving the last
* state to be handled (i.e., release resources or do other cleanup).
*
* @return a {@link Flux}
*/
public static Flux generate(Callable stateSupplier, BiFunction, S> generator, Consumer super S> stateConsumer) {
return onAssembly(new FluxGenerate<>(stateSupplier, generator, stateConsumer));
}
/**
* Create a {@link Flux} that emits long values starting with 0 and incrementing at
* specified time intervals on the global timer. The first element is emitted after
* an initial delay equal to the {@code period}. If demand is not produced in time,
* an onError will be signalled with an {@link Exceptions#isOverflow(Throwable) overflow}
* {@code IllegalStateException} detailing the tick that couldn't be emitted.
* In normal conditions, the {@link Flux} will never complete.
*
* Runs on the {@link Schedulers#parallel()} Scheduler.
*
*
*
* @param period the period {@link Duration} between each increment
* @return a new {@link Flux} emitting increasing numbers at regular intervals
*/
public static Flux interval(Duration period) {
return interval(period, Schedulers.parallel());
}
/**
* Create a {@link Flux} that emits long values starting with 0 and incrementing at
* specified time intervals, after an initial delay, on the global timer. If demand is
* not produced in time, an onError will be signalled with an
* {@link Exceptions#isOverflow(Throwable) overflow} {@code IllegalStateException}
* detailing the tick that couldn't be emitted. In normal conditions, the {@link Flux}
* will never complete.
*
* Runs on the {@link Schedulers#parallel()} Scheduler.
*
*
*
* @param delay the {@link Duration} to wait before emitting 0l
* @param period the period {@link Duration} before each following increment
*
* @return a new {@link Flux} emitting increasing numbers at regular intervals
*/
public static Flux interval(Duration delay, Duration period) {
return interval(delay, period, Schedulers.parallel());
}
/**
* Create a {@link Flux} that emits long values starting with 0 and incrementing at
* specified time intervals, on the specified {@link Scheduler}. The first element is
* emitted after an initial delay equal to the {@code period}. If demand is not
* produced in time, an onError will be signalled with an {@link Exceptions#isOverflow(Throwable) overflow}
* {@code IllegalStateException} detailing the tick that couldn't be emitted.
* In normal conditions, the {@link Flux} will never complete.
*
*
*
* @param period the period {@link Duration} between each increment
* @param timer a time-capable {@link Scheduler} instance to run on
*
* @return a new {@link Flux} emitting increasing numbers at regular intervals
*/
public static Flux interval(Duration period, Scheduler timer) {
return interval(period, period, timer);
}
/**
* Create a {@link Flux} that emits long values starting with 0 and incrementing at
* specified time intervals, after an initial delay, on the specified {@link Scheduler}.
* If demand is not produced in time, an onError will be signalled with an
* {@link Exceptions#isOverflow(Throwable) overflow} {@code IllegalStateException}
* detailing the tick that couldn't be emitted. In normal conditions, the {@link Flux}
* will never complete.
*
*
*
* @param delay the {@link Duration} to wait before emitting 0l
* @param period the period {@link Duration} before each following increment
* @param timer a time-capable {@link Scheduler} instance to run on
*
* @return a new {@link Flux} emitting increasing numbers at regular intervals
*/
public static Flux interval(Duration delay, Duration period, Scheduler timer) {
return onAssembly(new FluxInterval(delay.toNanos(), period.toNanos(), TimeUnit.NANOSECONDS, timer));
}
/**
* Create a {@link Flux} that emits the provided elements and then completes.
*
*
*
* @param data the elements to emit, as a vararg
* @param the emitted data type
*
* @return a new {@link Flux}
*/
@SafeVarargs
public static Flux just(T... data) {
return fromArray(data);
}
/**
* Create a new {@link Flux} that will only emit a single element then onComplete.
*
*
*
* @param data the single element to emit
* @param the emitted data type
*
* @return a new {@link Flux}
*/
public static Flux just(T data) {
return onAssembly(new FluxJust<>(data));
}
/**
* Merge data from {@link Publisher} sequences emitted by the passed {@link Publisher}
* into an interleaved merged sequence. Unlike {@link #concat(Publisher) concat}, inner
* sources are subscribed to eagerly.
*
*
*
*
* Note that merge is tailored to work with asynchronous sources or finite sources. When dealing with
* an infinite source that doesn't already publish on a dedicated Scheduler, you must isolate that source
* in its own Scheduler, as merge would otherwise attempt to drain it before subscribing to
* another source.
*
* @param source a {@link Publisher} of {@link Publisher} sources to merge
* @param the merged type
*
* @return a merged {@link Flux}
*/
public static Flux merge(Publisher extends Publisher extends T>> source) {
return merge(source,
Queues.SMALL_BUFFER_SIZE,
Queues.XS_BUFFER_SIZE);
}
/**
* Merge data from {@link Publisher} sequences emitted by the passed {@link Publisher}
* into an interleaved merged sequence. Unlike {@link #concat(Publisher) concat}, inner
* sources are subscribed to eagerly (but at most {@code concurrency} sources are
* subscribed to at the same time).
*
*
*
* Note that merge is tailored to work with asynchronous sources or finite sources. When dealing with
* an infinite source that doesn't already publish on a dedicated Scheduler, you must isolate that source
* in its own Scheduler, as merge would otherwise attempt to drain it before subscribing to
* another source.
*
* @param source a {@link Publisher} of {@link Publisher} sources to merge
* @param concurrency the request produced to the main source thus limiting concurrent merge backlog
* @param the merged type
*
* @return a merged {@link Flux}
*/
public static Flux merge(Publisher extends Publisher extends T>> source, int concurrency) {
return merge(source, concurrency, Queues.XS_BUFFER_SIZE);
}
/**
* Merge data from {@link Publisher} sequences emitted by the passed {@link Publisher}
* into an interleaved merged sequence. Unlike {@link #concat(Publisher) concat}, inner
* sources are subscribed to eagerly (but at most {@code concurrency} sources are
* subscribed to at the same time).
*
*
*
* Note that merge is tailored to work with asynchronous sources or finite sources. When dealing with
* an infinite source that doesn't already publish on a dedicated Scheduler, you must isolate that source
* in its own Scheduler, as merge would otherwise attempt to drain it before subscribing to
* another source.
*
* @param source a {@link Publisher} of {@link Publisher} sources to merge
* @param concurrency the request produced to the main source thus limiting concurrent merge backlog
* @param prefetch the inner source request size
* @param the merged type
*
* @return a merged {@link Flux}
*/
public static Flux merge(Publisher extends Publisher extends T>> source, int concurrency, int prefetch) {
return onAssembly(new FluxFlatMap<>(
from(source),
identityFunction(),
false,
concurrency,
Queues.get(concurrency),
prefetch,
Queues.get(prefetch)));
}
/**
* Merge data from {@link Publisher} sequences contained in an {@link Iterable}
* into an interleaved merged sequence. Unlike {@link #concat(Publisher) concat}, inner
* sources are subscribed to eagerly.
* A new {@link Iterator} will be created for each subscriber.
*
*
*
* Note that merge is tailored to work with asynchronous sources or finite sources. When dealing with
* an infinite source that doesn't already publish on a dedicated Scheduler, you must isolate that source
* in its own Scheduler, as merge would otherwise attempt to drain it before subscribing to
* another source.
*
* @param sources the {@link Iterable} of sources to merge (will be lazily iterated on subscribe)
* @param The source type of the data sequence
*
* @return a merged {@link Flux}
*/
public static Flux merge(Iterable extends Publisher extends I>> sources) {
return merge(fromIterable(sources));
}
/**
* Merge data from {@link Publisher} sequences contained in an array / vararg
* into an interleaved merged sequence. Unlike {@link #concat(Publisher) concat},
* sources are subscribed to eagerly.
*
*
*
* Note that merge is tailored to work with asynchronous sources or finite sources. When dealing with
* an infinite source that doesn't already publish on a dedicated Scheduler, you must isolate that source
* in its own Scheduler, as merge would otherwise attempt to drain it before subscribing to
* another source.
*
* @param sources the array of {@link Publisher} sources to merge
* @param The source type of the data sequence
*
* @return a merged {@link Flux}
*/
@SafeVarargs
public static Flux merge(Publisher extends I>... sources) {
return merge(Queues.XS_BUFFER_SIZE, sources);
}
/**
* Merge data from {@link Publisher} sequences contained in an array / vararg
* into an interleaved merged sequence. Unlike {@link #concat(Publisher) concat},
* sources are subscribed to eagerly.
*
*
*
* Note that merge is tailored to work with asynchronous sources or finite sources. When dealing with
* an infinite source that doesn't already publish on a dedicated Scheduler, you must isolate that source
* in its own Scheduler, as merge would otherwise attempt to drain it before subscribing to
* another source.
*
* @param sources the array of {@link Publisher} sources to merge
* @param prefetch the inner source request size
* @param The source type of the data sequence
*
* @return a fresh Reactive {@link Flux} publisher ready to be subscribed
*/
@SafeVarargs
public static Flux merge(int prefetch, Publisher extends I>... sources) {
return merge(prefetch, false, sources);
}
/**
* Merge data from {@link Publisher} sequences contained in an array / vararg
* into an interleaved merged sequence. Unlike {@link #concat(Publisher) concat},
* sources are subscribed to eagerly.
* This variant will delay any error until after the rest of the merge backlog has been processed.
*
*
*
* Note that merge is tailored to work with asynchronous sources or finite sources. When dealing with
* an infinite source that doesn't already publish on a dedicated Scheduler, you must isolate that source
* in its own Scheduler, as merge would otherwise attempt to drain it before subscribing to
* another source.
*
* @param sources the array of {@link Publisher} sources to merge
* @param prefetch the inner source request size
* @param The source type of the data sequence
*
* @return a fresh Reactive {@link Flux} publisher ready to be subscribed
*/
@SafeVarargs
public static Flux mergeDelayError(int prefetch, Publisher extends I>... sources) {
return merge(prefetch, true, sources);
}
/**
* Merge data from provided {@link Publisher} sequences into an ordered merged sequence,
* by picking the smallest values from each source (as defined by their natural order) as they arrive .
* This is not a {@link #sort()}, as it doesn't consider the whole of each sequences. Unlike mergeComparing,
* this operator does not wait for a value from each source to arrive either.
*
* While this operator does retrieve at most one value from each source, it only compares values when two or more
* sources emit at the same time. In that case it picks the smallest of these competing values and continues doing so
* as long as there is demand. It is therefore best suited for asynchronous sources where you do not want to wait
* for a value from each source before emitting a value downstream.
*
*
*
* @param sources {@link Publisher} sources of {@link Comparable} to merge
* @param a {@link Comparable} merged type that has a {@link Comparator#naturalOrder() natural order}
* @return a merged {@link Flux} that compares the latest available value from each source, publishing the
* smallest value and replenishing the source that produced it.
*/
@SafeVarargs
public static > Flux mergePriority(Publisher extends I>... sources) {
return mergePriority(Queues.SMALL_BUFFER_SIZE, Comparator.naturalOrder(), sources);
}
/**
* Merge data from provided {@link Publisher} sequences into an ordered merged sequence,
* by picking the smallest values from each source (as defined by the provided
* {@link Comparator}) as they arrive . This is not a {@link #sort(Comparator)}, as it doesn't consider
* the whole of each sequences. Unlike mergeComparing, this operator does not wait for a value from each
* source to arrive either.
*
* While this operator does retrieve at most one value from each source, it only compares values when two or more
* sources emit at the same time. In that case it picks the smallest of these competing values and continues doing so
* as long as there is demand. It is therefore best suited for asynchronous sources where you do not want to wait
* for a value from each source before emitting a value downstream.
*
*
*
* @param comparator the {@link Comparator} to use to find the smallest value
* @param sources {@link Publisher} sources to merge
* @param the merged type
* @return a merged {@link Flux} that compares the latest available value from each source, publishing the
* smallest value and replenishing the source that produced it.
*/
@SafeVarargs
public static Flux mergePriority(Comparator super T> comparator, Publisher extends T>... sources) {
return mergePriority(Queues.SMALL_BUFFER_SIZE, comparator, sources);
}
/**
* Merge data from provided {@link Publisher} sequences into an ordered merged sequence,
* by picking the smallest values from each source (as defined by the provided
* {@link Comparator}) as they arrive . This is not a {@link #sort(Comparator)}, as it doesn't consider
* the whole of each sequences. Unlike mergeComparing, this operator does not wait for a value from each
* source to arrive either.
*
* While this operator does retrieve at most one value from each source, it only compares values when two or more
* sources emit at the same time. In that case it picks the smallest of these competing values and continues doing so
* as long as there is demand. It is therefore best suited for asynchronous sources where you do not want to wait
* for a value from each source before emitting a value downstream.
*
*
*
* @param prefetch the number of elements to prefetch from each source (avoiding too
* many small requests to the source when picking)
* @param comparator the {@link Comparator} to use to find the smallest value
* @param sources {@link Publisher} sources to merge
* @param the merged type
* @return a merged {@link Flux} that compares the latest available value from each source, publishing the
* smallest value and replenishing the source that produced it.
*/
@SafeVarargs
public static Flux mergePriority(int prefetch, Comparator super T> comparator, Publisher extends T>... sources) {
if (sources.length == 0) {
return empty();
}
if (sources.length == 1) {
return from(sources[0]);
}
return onAssembly(new FluxMergeComparing<>(prefetch, comparator, false, false, sources));
}
/**
* Merge data from provided {@link Publisher} sequences into an ordered merged sequence,
* by picking the smallest values from each source (as defined by the provided
* {@link Comparator}) as they arrive . This is not a {@link #sort(Comparator)}, as it doesn't consider
* the whole of each sequences. Unlike mergeComparing, this operator does not wait for a value from each
* source to arrive either.
*
* While this operator does retrieve at most one value from each source, it only compares values when two or more
* sources emit at the same time. In that case it picks the smallest of these competing values and continues doing so
* as long as there is demand. It is therefore best suited for asynchronous sources where you do not want to wait
* for a value from each source before emitting a value downstream.
*
* Note that it is delaying errors until all data is consumed.
*
*
*
* @param prefetch the number of elements to prefetch from each source (avoiding too
* many small requests to the source when picking)
* @param comparator the {@link Comparator} to use to find the smallest value
* @param sources {@link Publisher} sources to merge
* @param the merged type
* @return a merged {@link Flux} that compares the latest available value from each source, publishing the
* smallest value and replenishing the source that produced it.
*/
@SafeVarargs
public static Flux mergePriorityDelayError(int prefetch, Comparator super T> comparator, Publisher extends T>... sources) {
if (sources.length == 0) {
return empty();
}
if (sources.length == 1) {
return from(sources[0]);
}
return onAssembly(new FluxMergeComparing<>(prefetch, comparator, true, false, sources));
}
/**
* Merge data from provided {@link Publisher} sequences into an ordered merged sequence,
* by picking the smallest values from each source (as defined by their natural order).
* This is not a {@link #sort()}, as it doesn't consider the whole of each sequences.
*
* Instead, this operator considers only one value from each source and picks the
* smallest of all these values, then replenishes the slot for that picked source.
*
*
*
* @param sources {@link Publisher} sources of {@link Comparable} to merge
* @param a {@link Comparable} merged type that has a {@link Comparator#naturalOrder() natural order}
* @return a merged {@link Flux} that , subscribing early but keeping the original ordering
*/
@SafeVarargs
public static > Flux mergeComparing(Publisher extends I>... sources) {
return mergeComparing(Queues.SMALL_BUFFER_SIZE, Comparator.naturalOrder(), sources);
}
/**
* Merge data from provided {@link Publisher} sequences into an ordered merged sequence,
* by picking the smallest values from each source (as defined by the provided
* {@link Comparator}). This is not a {@link #sort(Comparator)}, as it doesn't consider
* the whole of each sequences.
*
* Instead, this operator considers only one value from each source and picks the
* smallest of all these values, then replenishes the slot for that picked source.
*
*
*
* @param comparator the {@link Comparator} to use to find the smallest value
* @param sources {@link Publisher} sources to merge
* @param the merged type
* @return a merged {@link Flux} that compares latest values from each source, using the
* smallest value and replenishing the source that produced it
*/
@SafeVarargs
public static Flux mergeComparing(Comparator super T> comparator, Publisher extends T>... sources) {
return mergeComparing(Queues.SMALL_BUFFER_SIZE, comparator, sources);
}
/**
* Merge data from provided {@link Publisher} sequences into an ordered merged sequence,
* by picking the smallest values from each source (as defined by the provided
* {@link Comparator}). This is not a {@link #sort(Comparator)}, as it doesn't consider
* the whole of each sequences.
*
* Instead, this operator considers only one value from each source and picks the
* smallest of all these values, then replenishes the slot for that picked source.
*
*
*
* @param prefetch the number of elements to prefetch from each source (avoiding too
* many small requests to the source when picking)
* @param comparator the {@link Comparator} to use to find the smallest value
* @param sources {@link Publisher} sources to merge
* @param the merged type
* @return a merged {@link Flux} that compares latest values from each source, using the
* smallest value and replenishing the source that produced it
*/
@SafeVarargs
public static Flux mergeComparing(int prefetch, Comparator super T> comparator, Publisher extends T>... sources) {
if (sources.length == 0) {
return empty();
}
if (sources.length == 1) {
return from(sources[0]);
}
return onAssembly(new FluxMergeComparing<>(prefetch, comparator, false, true, sources));
}
/**
* Merge data from provided {@link Publisher} sequences into an ordered merged sequence,
* by picking the smallest values from each source (as defined by the provided
* {@link Comparator}). This is not a {@link #sort(Comparator)}, as it doesn't consider
* the whole of each sequences.
*
* Instead, this operator considers only one value from each source and picks the
* smallest of all these values, then replenishes the slot for that picked source.
*
* Note that it is delaying errors until all data is consumed.
*
*
*
* @param prefetch the number of elements to prefetch from each source (avoiding too
* many small requests to the source when picking)
* @param comparator the {@link Comparator} to use to find the smallest value
* @param sources {@link Publisher} sources to merge
* @param the merged type
* @return a merged {@link Flux} that compares latest values from each source, using the
* smallest value and replenishing the source that produced it
*/
@SafeVarargs
public static Flux mergeComparingDelayError(int prefetch, Comparator super T> comparator, Publisher extends T>... sources) {
if (sources.length == 0) {
return empty();
}
if (sources.length == 1) {
return from(sources[0]);
}
return onAssembly(new FluxMergeComparing<>(prefetch, comparator, true, true, sources));
}
/**
* Merge data from provided {@link Publisher} sequences into an ordered merged sequence,
* by picking the smallest values from each source (as defined by their natural order).
* This is not a {@link #sort()}, as it doesn't consider the whole of each sequences.
*
* Instead, this operator considers only one value from each source and picks the
* smallest of all these values, then replenishes the slot for that picked source.
*
* Note that it is delaying errors until all data is consumed.
*
*
*
* @param sources {@link Publisher} sources of {@link Comparable} to merge
* @param a {@link Comparable} merged type that has a {@link Comparator#naturalOrder() natural order}
* @return a merged {@link Flux} that compares latest values from each source, using the
* smallest value and replenishing the source that produced it
* @deprecated Use {@link #mergeComparingDelayError(int, Comparator, Publisher[])} instead
* (as {@link #mergeComparing(Publisher[])} don't have this operator's delayError behavior).
* To be removed in 3.6.0 at the earliest.
*/
@SafeVarargs
@Deprecated
public static > Flux mergeOrdered(Publisher extends I>... sources) {
return mergeOrdered(Queues.SMALL_BUFFER_SIZE, Comparator.naturalOrder(), sources);
}
/**
* Merge data from provided {@link Publisher} sequences into an ordered merged sequence,
* by picking the smallest values from each source (as defined by the provided
* {@link Comparator}). This is not a {@link #sort(Comparator)}, as it doesn't consider
* the whole of each sequences.
*
* Instead, this operator considers only one value from each source and picks the
* smallest of all these values, then replenishes the slot for that picked source.
*
* Note that it is delaying errors until all data is consumed.
*
*
*
* @param comparator the {@link Comparator} to use to find the smallest value
* @param sources {@link Publisher} sources to merge
* @param the merged type
* @return a merged {@link Flux} that compares latest values from each source, using the
* smallest value and replenishing the source that produced it
* @deprecated Use {@link #mergeComparingDelayError(int, Comparator, Publisher[])} instead
* (as {@link #mergeComparing(Publisher[])} don't have this operator's delayError behavior).
* To be removed in 3.6.0 at the earliest.
*/
@SafeVarargs
@Deprecated
public static Flux mergeOrdered(Comparator super T> comparator, Publisher extends T>... sources) {
return mergeOrdered(Queues.SMALL_BUFFER_SIZE, comparator, sources);
}
/**
* Merge data from provided {@link Publisher} sequences into an ordered merged sequence,
* by picking the smallest values from each source (as defined by the provided
* {@link Comparator}). This is not a {@link #sort(Comparator)}, as it doesn't consider
* the whole of each sequences.
*
* Instead, this operator considers only one value from each source and picks the
* smallest of all these values, then replenishes the slot for that picked source.
*
* Note that it is delaying errors until all data is consumed.
*
*
*
* @param prefetch the number of elements to prefetch from each source (avoiding too
* many small requests to the source when picking)
* @param comparator the {@link Comparator} to use to find the smallest value
* @param sources {@link Publisher} sources to merge
* @param the merged type
* @return a merged {@link Flux} that compares latest values from each source, using the
* smallest value and replenishing the source that produced it
* @deprecated Use {@link #mergeComparingDelayError(int, Comparator, Publisher[])} instead
* (as {@link #mergeComparing(Publisher[])} don't have this operator's delayError behavior).
* To be removed in 3.6.0 at the earliest.
*/
@SafeVarargs
@Deprecated
public static Flux mergeOrdered(int prefetch, Comparator super T> comparator, Publisher extends T>... sources) {
if (sources.length == 0) {
return empty();
}
if (sources.length == 1) {
return from(sources[0]);
}
return onAssembly(new FluxMergeComparing<>(prefetch, comparator, true, true, sources));
}
/**
* Merge data from {@link Publisher} sequences emitted by the passed {@link Publisher}
* into an ordered merged sequence. Unlike concat, the inner publishers are subscribed to
* eagerly. Unlike merge, their emitted values are merged into the final sequence in
* subscription order.
*