io.reactivex.rxjava3.core.Completable Maven / Gradle / Ivy
Show all versions of rxjava Show documentation
/*
* Copyright (c) 2016-present, RxJava Contributors.
*
* 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
*
* http://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 io.reactivex.rxjava3.core;
import java.util.*;
import java.util.concurrent.*;
import org.reactivestreams.*;
import io.reactivex.rxjava3.annotations.*;
import io.reactivex.rxjava3.disposables.*;
import io.reactivex.rxjava3.exceptions.*;
import io.reactivex.rxjava3.functions.*;
import io.reactivex.rxjava3.internal.functions.*;
import io.reactivex.rxjava3.internal.fuseable.*;
import io.reactivex.rxjava3.internal.jdk8.*;
import io.reactivex.rxjava3.internal.observers.*;
import io.reactivex.rxjava3.internal.operators.completable.*;
import io.reactivex.rxjava3.internal.operators.maybe.*;
import io.reactivex.rxjava3.internal.operators.mixed.*;
import io.reactivex.rxjava3.internal.operators.single.SingleDelayWithCompletable;
import io.reactivex.rxjava3.observers.TestObserver;
import io.reactivex.rxjava3.plugins.RxJavaPlugins;
import io.reactivex.rxjava3.schedulers.Schedulers;
/**
* The {@code Completable} class represents a deferred computation without any value but
* only indication for completion or exception.
*
* {@code Completable} behaves similarly to {@link Observable} except that it can only emit either
* a completion or error signal (there is no {@code onNext} or {@code onSuccess} as with the other
* reactive types).
*
* The {@code Completable} class implements the {@link CompletableSource} base interface and the default consumer
* type it interacts with is the {@link CompletableObserver} via the {@link #subscribe(CompletableObserver)} method.
* The {@code Completable} operates with the following sequential protocol:
*
* onSubscribe (onError | onComplete)?
*
*
* Note that as with the {@code Observable} protocol, {@code onError} and {@code onComplete} are mutually exclusive events.
*
* Like {@code Observable}, a running {@code Completable} can be stopped through the {@link Disposable} instance
* provided to consumers through {@link CompletableObserver#onSubscribe}.
*
* Like an {@code Observable}, a {@code Completable} is lazy, can be either "hot" or "cold", synchronous or
* asynchronous. {@code Completable} instances returned by the methods of this class are cold
* and there is a standard hot implementation in the form of a subject:
* {@link io.reactivex.rxjava3.subjects.CompletableSubject CompletableSubject}.
*
* The documentation for this class makes use of marble diagrams. The following legend explains these diagrams:
*
*
*
* See {@link Flowable} or {@code Observable} for the
* implementation of the Reactive Pattern for a stream or vector of values.
*
* Example:
*
* Disposable d = Completable.complete()
* .delay(10, TimeUnit.SECONDS, Schedulers.io())
* .subscribeWith(new DisposableCompletableObserver() {
* @Override
* public void onStart() {
* System.out.println("Started");
* }
*
* @Override
* public void onError(Throwable error) {
* error.printStackTrace();
* }
*
* @Override
* public void onComplete() {
* System.out.println("Done!");
* }
* });
*
* Thread.sleep(5000);
*
* d.dispose();
*
*
* Note that by design, subscriptions via {@link #subscribe(CompletableObserver)} can't be disposed
* from the outside (hence the
* {@code void} return of the {@link #subscribe(CompletableObserver)} method) and it is the
* responsibility of the implementor of the {@code CompletableObserver} to allow this to happen.
* RxJava supports such usage with the standard
* {@link io.reactivex.rxjava3.observers.DisposableCompletableObserver DisposableCompletableObserver} instance.
* For convenience, the {@link #subscribeWith(CompletableObserver)} method is provided as well to
* allow working with a {@code CompletableObserver} (or subclass) instance to be applied with in
* a fluent manner (such as in the example above).
*
* @see io.reactivex.rxjava3.observers.DisposableCompletableObserver
*/
public abstract class Completable implements CompletableSource {
/**
* Returns a {@code Completable} which terminates as soon as one of the source {@code Completable}s
* terminates (normally or with an error) and disposes all other {@code Completable}s.
*
*
*
* - Scheduler:
* - {@code ambArray} does not operate by default on a particular {@link Scheduler}.
*
* @param sources the array of source {@code Completable}s. A subscription to each source will
* occur in the same order as in this array.
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code sources} is {@code null}
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
@SafeVarargs
public static Completable ambArray(@NonNull CompletableSource... sources) {
Objects.requireNonNull(sources, "sources is null");
if (sources.length == 0) {
return complete();
}
if (sources.length == 1) {
return wrap(sources[0]);
}
return RxJavaPlugins.onAssembly(new CompletableAmb(sources, null));
}
/**
* Returns a {@code Completable} which terminates as soon as one of the source {@code Completable}s in the {@link Iterable} sequence
* terminates (normally or with an error) and disposes all other {@code Completable}s.
*
*
*
* - Scheduler:
* - {@code amb} does not operate by default on a particular {@link Scheduler}.
*
* @param sources the {@code Iterable} of source {@code Completable}s. A subscription to each source will
* occur in the same order as in this {@code Iterable}.
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code sources} is {@code null}
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static Completable amb(@NonNull Iterable<@NonNull ? extends CompletableSource> sources) {
Objects.requireNonNull(sources, "sources is null");
return RxJavaPlugins.onAssembly(new CompletableAmb(null, sources));
}
/**
* Returns a {@code Completable} instance that completes immediately when subscribed to.
*
*
*
* - Scheduler:
* - {@code complete} does not operate by default on a particular {@link Scheduler}.
*
* @return the shared {@code Completable} instance
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static Completable complete() {
return RxJavaPlugins.onAssembly(CompletableEmpty.INSTANCE);
}
/**
* Returns a {@code Completable} which completes only when all sources complete, one after another.
*
*
*
* - Scheduler:
* - {@code concatArray} does not operate by default on a particular {@link Scheduler}.
*
* @param sources the sources to concatenate
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code sources} is {@code null}
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
@SafeVarargs
public static Completable concatArray(@NonNull CompletableSource... sources) {
Objects.requireNonNull(sources, "sources is null");
if (sources.length == 0) {
return complete();
} else
if (sources.length == 1) {
return wrap(sources[0]);
}
return RxJavaPlugins.onAssembly(new CompletableConcatArray(sources));
}
/**
* Returns a {@code Completable} which completes only when all sources complete, one after another.
*
*
*
* - Scheduler:
* - {@code concatArrayDelayError} does not operate by default on a particular {@link Scheduler}.
*
* @param sources the sources to concatenate
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code sources} is {@code null}
* @since 3.0.0
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
@SafeVarargs
public static Completable concatArrayDelayError(@NonNull CompletableSource... sources) {
return Flowable.fromArray(sources).concatMapCompletableDelayError(Functions.identity(), true, 2);
}
/**
* Returns a {@code Completable} which completes only when all sources complete, one after another.
*
*
*
* - Scheduler:
* - {@code concat} does not operate by default on a particular {@link Scheduler}.
*
* @param sources the sources to concatenate
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code sources} is {@code null}
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static Completable concat(@NonNull Iterable<@NonNull ? extends CompletableSource> sources) {
Objects.requireNonNull(sources, "sources is null");
return RxJavaPlugins.onAssembly(new CompletableConcatIterable(sources));
}
/**
* Returns a {@code Completable} which completes only when all sources complete, one after another.
*
*
*
* - Backpressure:
* - The returned {@code Completable} honors the backpressure of the downstream consumer
* and expects the other {@link Publisher} to honor it as well.
* - Scheduler:
* - {@code concat} does not operate by default on a particular {@link Scheduler}.
*
* @param sources the sources to concatenate
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code sources} is {@code null}
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@BackpressureSupport(BackpressureKind.FULL)
@NonNull
public static Completable concat(@NonNull Publisher<@NonNull ? extends CompletableSource> sources) {
return concat(sources, 2);
}
/**
* Returns a {@code Completable} which completes only when all sources complete, one after another.
*
*
*
* - Backpressure:
* - The returned {@code Completable} honors the backpressure of the downstream consumer
* and expects the other {@link Publisher} to honor it as well.
* - Scheduler:
* - {@code concat} does not operate by default on a particular {@link Scheduler}.
*
* @param sources the sources to concatenate
* @param prefetch the number of sources to prefetch from the sources
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code sources} is {@code null}
* @throws IllegalArgumentException if {@code prefetch} is non-positive
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
@BackpressureSupport(BackpressureKind.FULL)
public static Completable concat(@NonNull Publisher<@NonNull ? extends CompletableSource> sources, int prefetch) {
Objects.requireNonNull(sources, "sources is null");
ObjectHelper.verifyPositive(prefetch, "prefetch");
return RxJavaPlugins.onAssembly(new CompletableConcat(sources, prefetch));
}
/**
* Returns a {@code Completable} which completes only when all sources complete, one after another.
*
*
*
* - Scheduler:
* - {@code concatDelayError} does not operate by default on a particular {@link Scheduler}.
*
* @param sources the sources to concatenate
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code sources} is {@code null}
* @since 3.0.0
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static Completable concatDelayError(@NonNull Iterable<@NonNull ? extends CompletableSource> sources) {
return Flowable.fromIterable(sources).concatMapCompletableDelayError(Functions.identity());
}
/**
* Returns a {@code Completable} which completes only when all sources complete, one after another.
*
*
*
* - Backpressure:
* - The returned {@code Completable} honors the backpressure of the downstream consumer
* and expects the other {@link Publisher} to honor it as well.
* - Scheduler:
* - {@code concatDelayError} does not operate by default on a particular {@link Scheduler}.
*
* @param sources the sources to concatenate
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code sources} is {@code null}
* @since 3.0.0
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@BackpressureSupport(BackpressureKind.FULL)
@NonNull
public static Completable concatDelayError(@NonNull Publisher<@NonNull ? extends CompletableSource> sources) {
return concatDelayError(sources, 2);
}
/**
* Returns a {@code Completable} which completes only when all sources complete, one after another.
*
*
*
* - Backpressure:
* - The returned {@code Completable} honors the backpressure of the downstream consumer
* and expects the other {@link Publisher} to honor it as well.
* - Scheduler:
* - {@code concatDelayError} does not operate by default on a particular {@link Scheduler}.
*
* @param sources the sources to concatenate
* @param prefetch the number of sources to prefetch from the sources
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code sources} is {@code null}
* @throws IllegalArgumentException if {@code prefetch} is non-positive
* @since 3.0.0
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
@BackpressureSupport(BackpressureKind.FULL)
public static Completable concatDelayError(@NonNull Publisher<@NonNull ? extends CompletableSource> sources, int prefetch) {
return Flowable.fromPublisher(sources).concatMapCompletableDelayError(Functions.identity(), true, prefetch);
}
/**
* Provides an API (via a cold {@code Completable}) that bridges the reactive world with the callback-style world.
*
*
*
* Example:
*
* Completable.create(emitter -> {
* Callback listener = new Callback() {
* @Override
* public void onEvent(Event e) {
* emitter.onComplete();
* }
*
* @Override
* public void onFailure(Exception e) {
* emitter.onError(e);
* }
* };
*
* AutoCloseable c = api.someMethod(listener);
*
* emitter.setCancellable(c::close);
*
* });
*
*
* Whenever a {@link CompletableObserver} subscribes to the returned {@code Completable}, the provided
* {@link CompletableOnSubscribe} callback is invoked with a fresh instance of a {@link CompletableEmitter}
* that will interact only with that specific {@code CompletableObserver}. If this {@code CompletableObserver}
* disposes the flow (making {@link CompletableEmitter#isDisposed} return {@code true}),
* other observers subscribed to the same returned {@code Completable} are not affected.
*
* - Scheduler:
* - {@code create} does not operate by default on a particular {@link Scheduler}.
*
* @param source the emitter that is called when a {@code CompletableObserver} subscribes to the returned {@code Completable}
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code source} is {@code null}
* @see CompletableOnSubscribe
* @see Cancellable
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static Completable create(@NonNull CompletableOnSubscribe source) {
Objects.requireNonNull(source, "source is null");
return RxJavaPlugins.onAssembly(new CompletableCreate(source));
}
/**
* Compares two {@link CompletableSource}s and emits {@code true} via a {@link Single} if both complete.
*
*
*
* - Scheduler:
* - {@code sequenceEqual} does not operate by default on a particular {@link Scheduler}.
*
* @param source1 the first {@code CompletableSource} instance
* @param source2 the second {@code CompletableSource} instance
* @return the new {@code Single} instance
* @throws NullPointerException if {@code source1} or {@code source2} is {@code null}
* @since 3.0.0
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static Single sequenceEqual(@NonNull CompletableSource source1, @NonNull CompletableSource source2) { // NOPMD
Objects.requireNonNull(source1, "source1 is null");
Objects.requireNonNull(source2, "source2 is null");
return mergeArrayDelayError(source1, source2).andThen(Single.just(true));
}
/**
* Constructs a {@code Completable} instance by wrapping the given source callback
* without any safeguards; you should manage the lifecycle and response
* to downstream disposal.
*
*
*
* - Scheduler:
* - {@code unsafeCreate} does not operate by default on a particular {@link Scheduler}.
*
* @param onSubscribe the callback which will receive the {@link CompletableObserver} instances
* when the {@code Completable} is subscribed to.
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code onSubscribe} is {@code null}
* @throws IllegalArgumentException if {@code source} is a {@code Completable}
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static Completable unsafeCreate(@NonNull CompletableSource onSubscribe) {
Objects.requireNonNull(onSubscribe, "onSubscribe is null");
if (onSubscribe instanceof Completable) {
throw new IllegalArgumentException("Use of unsafeCreate(Completable)!");
}
return RxJavaPlugins.onAssembly(new CompletableFromUnsafeSource(onSubscribe));
}
/**
* Defers the subscription to a {@code Completable} instance returned by a supplier.
*
*
*
* - Scheduler:
* - {@code defer} does not operate by default on a particular {@link Scheduler}.
*
* @param supplier the supplier that returns the {@code Completable} that will be subscribed to.
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code supplier} is {@code null}
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static Completable defer(@NonNull Supplier extends @NonNull CompletableSource> supplier) {
Objects.requireNonNull(supplier, "supplier is null");
return RxJavaPlugins.onAssembly(new CompletableDefer(supplier));
}
/**
* Creates a {@code Completable} which calls the given error supplier for each subscriber
* and emits its returned {@link Throwable}.
*
*
*
* If the {@code errorSupplier} returns {@code null}, the downstream {@link CompletableObserver}s will receive a
* {@link NullPointerException}.
*
* - Scheduler:
* - {@code error} does not operate by default on a particular {@link Scheduler}.
*
* @param supplier the error supplier, not {@code null}
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code supplier} is {@code null}
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static Completable error(@NonNull Supplier extends @NonNull Throwable> supplier) {
Objects.requireNonNull(supplier, "supplier is null");
return RxJavaPlugins.onAssembly(new CompletableErrorSupplier(supplier));
}
/**
* Creates a {@code Completable} instance that emits the given {@link Throwable} exception to subscribers.
*
*
*
* - Scheduler:
* - {@code error} does not operate by default on a particular {@link Scheduler}.
*
* @param throwable the {@code Throwable} instance to emit, not {@code null}
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code throwable} is {@code null}
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static Completable error(@NonNull Throwable throwable) {
Objects.requireNonNull(throwable, "throwable is null");
return RxJavaPlugins.onAssembly(new CompletableError(throwable));
}
/**
* Returns a {@code Completable} instance that runs the given {@link Action} for each {@link CompletableObserver} and
* emits either an exception or simply completes.
*
*
*
* - Scheduler:
* - {@code fromAction} does not operate by default on a particular {@link Scheduler}.
* - Error handling:
* - If the {@code Action} throws an exception, the respective {@link Throwable} is
* delivered to the downstream via {@link CompletableObserver#onError(Throwable)},
* except when the downstream has disposed this {@code Completable} source.
* In this latter case, the {@code Throwable} is delivered to the global error handler via
* {@link RxJavaPlugins#onError(Throwable)} as an {@link io.reactivex.rxjava3.exceptions.UndeliverableException UndeliverableException}.
*
*
* @param action the {@code Action} to run for each subscribing {@code CompletableObserver}
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code action} is {@code null}
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static Completable fromAction(@NonNull Action action) {
Objects.requireNonNull(action, "action is null");
return RxJavaPlugins.onAssembly(new CompletableFromAction(action));
}
/**
* Returns a {@code Completable} which when subscribed, executes the {@link Callable} function, ignores its
* normal result and emits {@code onError} or {@code onComplete} only.
*
*
*
* - Scheduler:
* - {@code fromCallable} does not operate by default on a particular {@link Scheduler}.
* - Error handling:
* - If the {@code Callable} throws an exception, the respective {@link Throwable} is
* delivered to the downstream via {@link CompletableObserver#onError(Throwable)},
* except when the downstream has disposed this {@code Completable} source.
* In this latter case, the {@code Throwable} is delivered to the global error handler via
* {@link RxJavaPlugins#onError(Throwable)} as an {@link io.reactivex.rxjava3.exceptions.UndeliverableException UndeliverableException}.
*
*
* @param callable the {@code Callable} instance to execute for each subscribing {@link CompletableObserver}
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code callable} is {@code null}
* @see #defer(Supplier)
* @see #fromSupplier(Supplier)
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static Completable fromCallable(@NonNull Callable> callable) {
Objects.requireNonNull(callable, "callable is null");
return RxJavaPlugins.onAssembly(new CompletableFromCallable(callable));
}
/**
* Returns a {@code Completable} instance that reacts to the termination of the given {@link Future} in a blocking fashion.
*
*
*
* Note that disposing the {@code Completable} won't cancel the {@code Future}.
* Use {@link #doOnDispose(Action)} and call {@link Future#cancel(boolean)} in the
* {@link Action}.
*
* - Scheduler:
* - {@code fromFuture} does not operate by default on a particular {@link Scheduler}.
*
* @param future the {@code Future} to react to
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code future} is {@code null}
* @see #fromCompletionStage(CompletionStage)
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static Completable fromFuture(@NonNull Future> future) {
Objects.requireNonNull(future, "future is null");
return fromAction(Functions.futureAction(future));
}
/**
* Returns a {@code Completable} instance that when subscribed to, subscribes to the {@link MaybeSource} instance and
* emits an {@code onComplete} event if the maybe emits {@code onSuccess}/{@code onComplete} or forwards any
* {@code onError} events.
*
*
*
* - Scheduler:
* - {@code fromMaybe} does not operate by default on a particular {@link Scheduler}.
*
* History: 2.1.17 - beta
* @param the value type of the {@code MaybeSource} element
* @param maybe the {@code MaybeSource} instance to subscribe to, not {@code null}
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code maybe} is {@code null}
* @since 2.2
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Completable fromMaybe(@NonNull MaybeSource maybe) {
Objects.requireNonNull(maybe, "maybe is null");
return RxJavaPlugins.onAssembly(new MaybeIgnoreElementCompletable<>(maybe));
}
/**
* Returns a {@code Completable} instance that runs the given {@link Runnable} for each {@link CompletableObserver} and
* emits either its unchecked exception or simply completes.
*
*
*
* If the code to be wrapped needs to throw a checked or more broader {@link Throwable} exception, that
* exception has to be converted to an unchecked exception by the wrapped code itself. Alternatively,
* use the {@link #fromAction(Action)} method which allows the wrapped code to throw any {@code Throwable}
* exception and will signal it to observers as-is.
*
* - Scheduler:
* - {@code fromRunnable} does not operate by default on a particular {@link Scheduler}.
* - Error handling:
* - If the {@code Runnable} throws an exception, the respective {@code Throwable} is
* delivered to the downstream via {@link CompletableObserver#onError(Throwable)},
* except when the downstream has disposed this {@code Completable} source.
* In this latter case, the {@code Throwable} is delivered to the global error handler via
* {@link RxJavaPlugins#onError(Throwable)} as an {@link io.reactivex.rxjava3.exceptions.UndeliverableException UndeliverableException}.
*
*
* @param run the {@code Runnable} to run for each {@code CompletableObserver}
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code run} is {@code null}
* @see #fromAction(Action)
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static Completable fromRunnable(@NonNull Runnable run) {
Objects.requireNonNull(run, "run is null");
return RxJavaPlugins.onAssembly(new CompletableFromRunnable(run));
}
/**
* Returns a {@code Completable} instance that subscribes to the given {@link ObservableSource}, ignores all values and
* emits only the terminal event.
*
*
*
* - Scheduler:
* - {@code fromObservable} does not operate by default on a particular {@link Scheduler}.
*
* @param the type of the {@code ObservableSource}
* @param observable the {@code ObservableSource} instance to subscribe to, not {@code null}
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code observable} is {@code null}
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Completable fromObservable(@NonNull ObservableSource observable) {
Objects.requireNonNull(observable, "observable is null");
return RxJavaPlugins.onAssembly(new CompletableFromObservable<>(observable));
}
/**
* Returns a {@code Completable} instance that subscribes to the given {@link Publisher}, ignores all values and
* emits only the terminal event.
*
*
*
* The {@code Publisher} must follow the
* Reactive-Streams specification.
* Violating the specification may result in undefined behavior.
*
* If possible, use {@link #create(CompletableOnSubscribe)} to create a
* source-like {@code Completable} instead.
*
* Note that even though {@code Publisher} appears to be a functional interface, it
* is not recommended to implement it through a lambda as the specification requires
* state management that is not achievable with a stateless lambda.
*
* - Backpressure:
* - The returned {@code Completable} honors the backpressure of the downstream consumer
* and expects the other {@code Publisher} to honor it as well.
* - Scheduler:
* - {@code fromPublisher} does not operate by default on a particular {@link Scheduler}.
*
* @param the type of the {@code Publisher}
* @param publisher the {@code Publisher} instance to subscribe to, not {@code null}
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code publisher} is {@code null}
* @see #create(CompletableOnSubscribe)
*/
@CheckReturnValue
@NonNull
@BackpressureSupport(BackpressureKind.UNBOUNDED_IN)
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Completable fromPublisher(@NonNull Publisher publisher) {
Objects.requireNonNull(publisher, "publisher is null");
return RxJavaPlugins.onAssembly(new CompletableFromPublisher<>(publisher));
}
/**
* Returns a {@code Completable} instance that when subscribed to, subscribes to the {@link SingleSource} instance and
* emits a completion event if the single emits {@code onSuccess} or forwards any {@code onError} events.
*
*
*
* - Scheduler:
* - {@code fromSingle} does not operate by default on a particular {@link Scheduler}.
*
* @param the value type of the {@code SingleSource}
* @param single the {@code SingleSource} instance to subscribe to, not {@code null}
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code single} is {@code null}
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull T> Completable fromSingle(@NonNull SingleSource single) {
Objects.requireNonNull(single, "single is null");
return RxJavaPlugins.onAssembly(new CompletableFromSingle<>(single));
}
/**
* Returns a {@code Completable} which when subscribed, executes the {@link Supplier} function, ignores its
* normal result and emits {@code onError} or {@code onComplete} only.
*
*
*
* - Scheduler:
* - {@code fromSupplier} does not operate by default on a particular {@link Scheduler}.
* - Error handling:
* - If the {@code Supplier} throws an exception, the respective {@link Throwable} is
* delivered to the downstream via {@link CompletableObserver#onError(Throwable)},
* except when the downstream has disposed this {@code Completable} source.
* In this latter case, the {@code Throwable} is delivered to the global error handler via
* {@link RxJavaPlugins#onError(Throwable)} as an {@link io.reactivex.rxjava3.exceptions.UndeliverableException UndeliverableException}.
*
*
* @param supplier the {@code Supplier} instance to execute for each {@link CompletableObserver}
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code supplier} is {@code null}
* @see #defer(Supplier)
* @see #fromCallable(Callable)
* @since 3.0.0
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static Completable fromSupplier(@NonNull Supplier> supplier) {
Objects.requireNonNull(supplier, "supplier is null");
return RxJavaPlugins.onAssembly(new CompletableFromSupplier(supplier));
}
/**
* Returns a {@code Completable} instance that subscribes to all sources at once and
* completes only when all source {@link CompletableSource}s complete or one of them emits an error.
*
*
*
* - Scheduler:
* - {@code mergeArray} does not operate by default on a particular {@link Scheduler}.
* - Error handling:
* - If any of the source {@code CompletableSource}s signal a {@link Throwable} via {@code onError}, the resulting
* {@code Completable} terminates with that {@code Throwable} and all other source {@code CompletableSource}s are disposed.
* If more than one {@code CompletableSource} signals an error, the resulting {@code Completable} may terminate with the
* first one's error or, depending on the concurrency of the sources, may terminate with a
* {@link CompositeException} containing two or more of the various error signals.
* {@code Throwable}s that didn't make into the composite will be sent (individually) to the global error handler via
* {@link RxJavaPlugins#onError(Throwable)} method as {@link UndeliverableException} errors. Similarly, {@code Throwable}s
* signaled by source(s) after the returned {@code Completable} has been disposed or terminated with a
* (composite) error will be sent to the same global error handler.
* Use {@link #mergeArrayDelayError(CompletableSource...)} to merge sources and terminate only when all source {@code CompletableSource}s
* have completed or failed with an error.
*
*
* @param sources the array of {@code CompletableSource}s.
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code sources} is {@code null}
* @see #mergeArrayDelayError(CompletableSource...)
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
@SafeVarargs
public static Completable mergeArray(@NonNull CompletableSource... sources) {
Objects.requireNonNull(sources, "sources is null");
if (sources.length == 0) {
return complete();
} else
if (sources.length == 1) {
return wrap(sources[0]);
}
return RxJavaPlugins.onAssembly(new CompletableMergeArray(sources));
}
/**
* Returns a {@code Completable} instance that subscribes to all sources at once and
* completes only when all source {@link CompletableSource}s complete or one of them emits an error.
*
*
*
* - Scheduler:
* - {@code merge} does not operate by default on a particular {@link Scheduler}.
* - Error handling:
* - If any of the source {@code CompletableSource}s signal a {@link Throwable} via {@code onError}, the resulting
* {@code Completable} terminates with that {@code Throwable} and all other source {@code CompletableSource}s are disposed.
* If more than one {@code CompletableSource} signals an error, the resulting {@code Completable} may terminate with the
* first one's error or, depending on the concurrency of the sources, may terminate with a
* {@link CompositeException} containing two or more of the various error signals.
* {@code Throwable}s that didn't make into the composite will be sent (individually) to the global error handler via
* {@link RxJavaPlugins#onError(Throwable)} method as {@link UndeliverableException} errors. Similarly, {@code Throwable}s
* signaled by source(s) after the returned {@code Completable} has been disposed or terminated with a
* (composite) error will be sent to the same global error handler.
* Use {@link #mergeDelayError(Iterable)} to merge sources and terminate only when all source {@code CompletableSource}s
* have completed or failed with an error.
*
*
* @param sources the {@link Iterable} sequence of {@code CompletableSource}s.
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code sources} is {@code null}
* @see #mergeDelayError(Iterable)
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static Completable merge(@NonNull Iterable<@NonNull ? extends CompletableSource> sources) {
Objects.requireNonNull(sources, "sources is null");
return RxJavaPlugins.onAssembly(new CompletableMergeIterable(sources));
}
/**
* Returns a {@code Completable} instance that subscribes to all sources at once and
* completes only when all source {@link CompletableSource}s complete or one of them emits an error.
*
*
*
* - Backpressure:
* - The operator consumes the given {@link Publisher} in an unbounded manner
* (requesting {@link Long#MAX_VALUE} upfront).
* - Scheduler:
* - {@code merge} does not operate by default on a particular {@link Scheduler}.
* - Error handling:
* - If any of the source {@code CompletableSource}s signal a {@link Throwable} via {@code onError}, the resulting
* {@code Completable} terminates with that {@code Throwable} and all other source {@code CompletableSource}s are disposed.
* If more than one {@code CompletableSource} signals an error, the resulting {@code Completable} may terminate with the
* first one's error or, depending on the concurrency of the sources, may terminate with a
* {@link CompositeException} containing two or more of the various error signals.
* {@code Throwable}s that didn't make into the composite will be sent (individually) to the global error handler via
* {@link RxJavaPlugins#onError(Throwable)} method as {@link UndeliverableException} errors. Similarly, {@code Throwable}s
* signaled by source(s) after the returned {@code Completable} has been disposed or terminated with a
* (composite) error will be sent to the same global error handler.
* Use {@link #mergeDelayError(Publisher)} to merge sources and terminate only when all source {@code CompletableSource}s
* have completed or failed with an error.
*
*
* @param sources the {@code Publisher} sequence of {@code CompletableSource}s.
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code sources} is {@code null}
* @see #mergeDelayError(Publisher)
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@BackpressureSupport(BackpressureKind.UNBOUNDED_IN)
@NonNull
public static Completable merge(@NonNull Publisher<@NonNull ? extends CompletableSource> sources) {
return merge0(sources, Integer.MAX_VALUE, false);
}
/**
* Returns a {@code Completable} instance that keeps subscriptions to a limited number of sources at once and
* completes only when all source {@link CompletableSource}s complete or one of them emits an error.
*
*
*
* - Backpressure:
* - The operator consumes the given {@link Publisher} in a bounded manner,
* requesting {@code maxConcurrency} items first, then keeps requesting as
* many more as the inner {@code CompletableSource}s terminate.
* - Scheduler:
* - {@code merge} does not operate by default on a particular {@link Scheduler}.
* - Error handling:
* - If any of the source {@code CompletableSource}s signal a {@link Throwable} via {@code onError}, the resulting
* {@code Completable} terminates with that {@code Throwable} and all other source {@code CompletableSource}s are disposed.
* If more than one {@code CompletableSource} signals an error, the resulting {@code Completable} may terminate with the
* first one's error or, depending on the concurrency of the sources, may terminate with a
* {@link CompositeException} containing two or more of the various error signals.
* {@code Throwable}s that didn't make into the composite will be sent (individually) to the global error handler via
* {@link RxJavaPlugins#onError(Throwable)} method as {@link UndeliverableException} errors. Similarly, {@code Throwable}s
* signaled by source(s) after the returned {@code Completable} has been disposed or terminated with a
* (composite) error will be sent to the same global error handler.
* Use {@link #mergeDelayError(Publisher, int)} to merge sources and terminate only when all source {@code CompletableSource}s
* have completed or failed with an error.
*
*
* @param sources the {@code Publisher} sequence of {@code CompletableSource}s.
* @param maxConcurrency the maximum number of concurrent subscriptions
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code sources} is {@code null}
* @throws IllegalArgumentException if {@code maxConcurrency} is less than 1
* @see #mergeDelayError(Publisher, int)
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@BackpressureSupport(BackpressureKind.FULL)
@NonNull
public static Completable merge(@NonNull Publisher<@NonNull ? extends CompletableSource> sources, int maxConcurrency) {
return merge0(sources, maxConcurrency, false);
}
/**
* Returns a {@code Completable} instance that keeps subscriptions to a limited number of {@link CompletableSource}s at once and
* completes only when all source {@code CompletableSource}s terminate in one way or another, combining any exceptions
* signaled by either the source {@link Publisher} or the inner {@code CompletableSource} instances.
*
* - Backpressure:
* - The operator consumes the given {@code Publisher} in a bounded manner,
* requesting {@code maxConcurrency} items first, then keeps requesting as
* many more as the inner {@code CompletableSource}s terminate.
* - Scheduler:
* - {@code merge0} does not operate by default on a particular {@link Scheduler}.
*
* @param sources the {@code Publisher} sequence of {@code CompletableSource}s.
* @param maxConcurrency the maximum number of concurrent subscriptions
* @param delayErrors delay all errors from the main source and from the inner {@code CompletableSource}s?
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code sources} is {@code null}
* @throws IllegalArgumentException if {@code maxConcurrency} is less than 1
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
@BackpressureSupport(BackpressureKind.FULL)
private static Completable merge0(@NonNull Publisher<@NonNull ? extends CompletableSource> sources, int maxConcurrency, boolean delayErrors) {
Objects.requireNonNull(sources, "sources is null");
ObjectHelper.verifyPositive(maxConcurrency, "maxConcurrency");
return RxJavaPlugins.onAssembly(new CompletableMerge(sources, maxConcurrency, delayErrors));
}
/**
* Returns a {@code Completable} that subscribes to all {@link CompletableSource}s in the source array and delays
* any error emitted by any of the inner {@code CompletableSource}s until all of
* them terminate in a way or another.
*
*
*
* - Scheduler:
* - {@code mergeArrayDelayError} does not operate by default on a particular {@link Scheduler}.
*
* @param sources the array of {@code CompletableSource}s
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code sources} is {@code null}
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
@SafeVarargs
public static Completable mergeArrayDelayError(@NonNull CompletableSource... sources) {
Objects.requireNonNull(sources, "sources is null");
return RxJavaPlugins.onAssembly(new CompletableMergeArrayDelayError(sources));
}
/**
* Returns a {@code Completable} that subscribes to all {@link CompletableSource}s in the source sequence and delays
* any error emitted by any of the inner {@code CompletableSource}s until all of
* them terminate in a way or another.
*
*
*
* - Scheduler:
* - {@code mergeDelayError} does not operate by default on a particular {@link Scheduler}.
*
* @param sources the sequence of {@code CompletableSource}s
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code sources} is {@code null}
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static Completable mergeDelayError(@NonNull Iterable<@NonNull ? extends CompletableSource> sources) {
Objects.requireNonNull(sources, "sources is null");
return RxJavaPlugins.onAssembly(new CompletableMergeDelayErrorIterable(sources));
}
/**
* Returns a {@code Completable} that subscribes to all {@link CompletableSource}s in the source sequence and delays
* any error emitted by either the sources {@link Publisher} or any of the inner {@code CompletableSource}s until all of
* them terminate in a way or another.
*
*
*
* - Backpressure:
* - The operator consumes the {@code Publisher} in an unbounded manner
* (requesting {@link Long#MAX_VALUE} from it).
* - Scheduler:
* - {@code mergeDelayError} does not operate by default on a particular {@link Scheduler}.
*
* @param sources the sequence of {@code CompletableSource}s
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code sources} is {@code null}
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@BackpressureSupport(BackpressureKind.UNBOUNDED_IN)
@NonNull
public static Completable mergeDelayError(@NonNull Publisher<@NonNull ? extends CompletableSource> sources) {
return merge0(sources, Integer.MAX_VALUE, true);
}
/**
* Returns a {@code Completable} that subscribes to a limited number of inner {@link CompletableSource}s at once in
* the source sequence and delays any error emitted by either the sources
* {@link Publisher} or any of the inner {@code CompletableSource}s until all of
* them terminate in a way or another.
*
*
*
* - Backpressure:
* - The operator requests {@code maxConcurrency} items from the {@code Publisher}
* upfront and keeps requesting as many more as many inner {@code CompletableSource}s terminate.
* - Scheduler:
* - {@code mergeDelayError} does not operate by default on a particular {@link Scheduler}.
*
* @param sources the sequence of {@code CompletableSource}s
* @param maxConcurrency the maximum number of concurrent subscriptions to have
* at a time to the inner {@code CompletableSource}s
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code sources} is {@code null}
* @throws IllegalArgumentException if {@code maxConcurrency} is non-positive
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@BackpressureSupport(BackpressureKind.FULL)
@NonNull
public static Completable mergeDelayError(@NonNull Publisher<@NonNull ? extends CompletableSource> sources, int maxConcurrency) {
return merge0(sources, maxConcurrency, true);
}
/**
* Returns a {@code Completable} that never calls {@code onError} or {@code onComplete}.
*
*
*
* - Scheduler:
* - {@code never} does not operate by default on a particular {@link Scheduler}.
*
* @return the singleton instance that never calls {@code onError} or {@code onComplete}
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@NonNull
public static Completable never() {
return RxJavaPlugins.onAssembly(CompletableNever.INSTANCE);
}
/**
* Returns a {@code Completable} instance that fires its {@code onComplete} event after the given delay elapsed.
*
*
*
* - Scheduler:
* - {@code timer} does operate by default on the {@code computation} {@link Scheduler}.
*
* @param delay the delay time
* @param unit the delay unit
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code unit} is {@code null}
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.COMPUTATION)
@NonNull
public static Completable timer(long delay, @NonNull TimeUnit unit) {
return timer(delay, unit, Schedulers.computation());
}
/**
* Returns a {@code Completable} instance that fires its {@code onComplete} event after the given delay elapsed
* by using the supplied {@link Scheduler}.
*
*
*
* - Scheduler:
* - {@code timer} operates on the {@code Scheduler} you specify.
*
* @param delay the delay time
* @param unit the delay unit
* @param scheduler the {@code Scheduler} where to emit the {@code onComplete} event
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code unit} or {@code scheduler} is {@code null}
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.CUSTOM)
public static Completable timer(long delay, @NonNull TimeUnit unit, @NonNull Scheduler scheduler) {
Objects.requireNonNull(unit, "unit is null");
Objects.requireNonNull(scheduler, "scheduler is null");
return RxJavaPlugins.onAssembly(new CompletableTimer(delay, unit, scheduler));
}
/**
* Creates a {@link NullPointerException} instance and sets the given {@link Throwable} as its initial cause.
* @param ex the {@code Throwable} instance to use as cause, not {@code null} (not verified)
* @return the new {@code NullPointerException}
*/
private static NullPointerException toNpe(Throwable ex) {
NullPointerException npe = new NullPointerException("Actually not, but can't pass out an exception otherwise...");
npe.initCause(ex);
return npe;
}
/**
* Switches between {@link CompletableSource}s emitted by the source {@link Publisher} whenever
* a new {@code CompletableSource} is emitted, disposing the previously running {@code CompletableSource},
* exposing the setup as a {@code Completable} sequence.
*
*
*
* - Backpressure:
* - The {@code sources} {@code Publisher} is consumed in an unbounded manner (requesting {@link Long#MAX_VALUE}).
* - Scheduler:
* - {@code switchOnNext} does not operate by default on a particular {@link Scheduler}.
* - Error handling:
* - The returned sequence fails with the first error signaled by the {@code sources} {@code Publisher}
* or the currently running {@code CompletableSource}, disposing the rest. Late errors are
* forwarded to the global error handler via {@link RxJavaPlugins#onError(Throwable)}.
*
* @param sources the {@code Publisher} sequence of inner {@code CompletableSource}s to switch between
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code sources} is {@code null}
* @since 3.0.0
* @see #switchOnNextDelayError(Publisher)
* @see ReactiveX operators documentation: Switch
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
@BackpressureSupport(BackpressureKind.UNBOUNDED_IN)
public static Completable switchOnNext(@NonNull Publisher<@NonNull ? extends CompletableSource> sources) {
Objects.requireNonNull(sources, "sources is null");
return RxJavaPlugins.onAssembly(new FlowableSwitchMapCompletablePublisher<>(sources, Functions.identity(), false));
}
/**
* Switches between {@link CompletableSource}s emitted by the source {@link Publisher} whenever
* a new {@code CompletableSource} is emitted, disposing the previously running {@code CompletableSource},
* exposing the setup as a {@code Completable} sequence and delaying all errors from
* all of them until all terminate.
*
*
*
* - Backpressure:
* - The {@code sources} {@code Publisher} is consumed in an unbounded manner (requesting {@link Long#MAX_VALUE}).
* - Scheduler:
* - {@code switchOnNextDelayError} does not operate by default on a particular {@link Scheduler}.
* - Error handling:
* - The returned {@code Completable} collects all errors emitted by either the {@code sources}
* {@code Publisher} or any inner {@code CompletableSource} and emits them as a {@link CompositeException}
* when all sources terminate. If only one source ever failed, its error is emitted as-is at the end.
*
* @param sources the {@code Publisher} sequence of inner {@code CompletableSource}s to switch between
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code sources} is {@code null}
* @since 3.0.0
* @see #switchOnNext(Publisher)
* @see ReactiveX operators documentation: Switch
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
@BackpressureSupport(BackpressureKind.UNBOUNDED_IN)
public static Completable switchOnNextDelayError(@NonNull Publisher<@NonNull ? extends CompletableSource> sources) {
Objects.requireNonNull(sources, "sources is null");
return RxJavaPlugins.onAssembly(new FlowableSwitchMapCompletablePublisher<>(sources, Functions.identity(), true));
}
/**
* Returns a {@code Completable} instance which manages a resource along
* with a custom {@link CompletableSource} instance while the subscription is active.
*
*
*
* This overload disposes eagerly before the terminal event is emitted.
*
* - Scheduler:
* - {@code using} does not operate by default on a particular {@link Scheduler}.
*
* @param the resource type
* @param resourceSupplier the {@link Supplier} that returns a resource to be managed.
* @param sourceSupplier the {@link Function} that given a resource returns a {@code CompletableSource} instance that will be subscribed to
* @param resourceCleanup the {@link Consumer} that disposes the resource created by the resource supplier
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code resourceSupplier}, {@code sourceSupplier}
* or {@code resourceCleanup} is {@code null}
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@NonNull
public static <@NonNull R> Completable using(@NonNull Supplier resourceSupplier,
@NonNull Function super R, ? extends CompletableSource> sourceSupplier,
@NonNull Consumer super R> resourceCleanup) {
return using(resourceSupplier, sourceSupplier, resourceCleanup, true);
}
/**
* Returns a {@code Completable} instance which manages a resource along
* with a custom {@link CompletableSource} instance while the subscription is active and performs eager or lazy
* resource disposition.
*
*
*
* If this overload performs a lazy disposal after the terminal event is emitted.
* The exceptions thrown at this time will be delivered to the global {@link RxJavaPlugins#onError(Throwable)} handler only.
*
* - Scheduler:
* - {@code using} does not operate by default on a particular {@link Scheduler}.
*
* @param the resource type
* @param resourceSupplier the {@link Supplier} that returns a resource to be managed
* @param sourceSupplier the {@link Function} that given a resource returns a non-{@code null}
* {@code CompletableSource} instance that will be subscribed to
* @param resourceCleanup the {@link Consumer} that disposes the resource created by the resource supplier
* @param eager
* If {@code true} then resource disposal will happen either on a {@code dispose()} call before the upstream is disposed
* or just before the emission of a terminal event ({@code onComplete} or {@code onError}).
* If {@code false} the resource disposal will happen either on a {@code dispose()} call after the upstream is disposed
* or just after the emission of a terminal event ({@code onComplete} or {@code onError}).
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code resourceSupplier}, {@code sourceSupplier}
* or {@code resourceCleanup} is {@code null}
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <@NonNull R> Completable using(
@NonNull Supplier resourceSupplier,
@NonNull Function super R, ? extends CompletableSource> sourceSupplier,
@NonNull Consumer super R> resourceCleanup,
boolean eager) {
Objects.requireNonNull(resourceSupplier, "resourceSupplier is null");
Objects.requireNonNull(sourceSupplier, "sourceSupplier is null");
Objects.requireNonNull(resourceCleanup, "resourceCleanup is null");
return RxJavaPlugins.onAssembly(new CompletableUsing<>(resourceSupplier, sourceSupplier, resourceCleanup, eager));
}
/**
* Wraps the given {@link CompletableSource} into a {@code Completable}
* if not already {@code Completable}.
*
*
*
* - Scheduler:
* - {@code wrap} does not operate by default on a particular {@link Scheduler}.
*
* @param source the source to wrap
* @return the new wrapped or cast {@code Completable} instance
* @throws NullPointerException if {@code source} is {@code null}
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static Completable wrap(@NonNull CompletableSource source) {
Objects.requireNonNull(source, "source is null");
if (source instanceof Completable) {
return RxJavaPlugins.onAssembly((Completable)source);
}
return RxJavaPlugins.onAssembly(new CompletableFromUnsafeSource(source));
}
/**
* Returns a {@code Completable} that emits the a terminated event of either this {@code Completable}
* or the other {@link CompletableSource}, whichever fires first.
*
*
*
* - Scheduler:
* - {@code ambWith} does not operate by default on a particular {@link Scheduler}.
*
* @param other the other {@code CompletableSource}, not {@code null}. A subscription to this provided source will occur after subscribing
* to the current source.
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code other} is {@code null}
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public final Completable ambWith(@NonNull CompletableSource other) {
Objects.requireNonNull(other, "other is null");
return ambArray(this, other);
}
/**
* Returns an {@link Observable} which will subscribe to this {@code Completable} and once that is completed then
* will subscribe to the {@code next} {@link ObservableSource}. An error event from this {@code Completable} will be
* propagated to the downstream observer and will result in skipping the subscription to the
* next {@code ObservableSource}.
*
*
*
* - Scheduler:
* - {@code andThen} does not operate by default on a particular {@link Scheduler}.
*
* @param the value type of the next {@code ObservableSource}
* @param next the {@code ObservableSource} to subscribe after this {@code Completable} is completed, not {@code null}
* @return the new {@code Observable} that composes this {@code Completable} and the next {@code ObservableSource}
* @throws NullPointerException if {@code next} is {@code null}
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public final <@NonNull T> Observable andThen(@NonNull ObservableSource next) {
Objects.requireNonNull(next, "next is null");
return RxJavaPlugins.onAssembly(new CompletableAndThenObservable<>(this, next));
}
/**
* Returns a {@link Flowable} which will subscribe to this {@code Completable} and once that is completed then
* will subscribe to the {@code next} {@link Publisher}. An error event from this {@code Completable} will be
* propagated to the downstream subscriber and will result in skipping the subscription to the next
* {@code Publisher}.
*
*
*
* - Backpressure:
* - The returned {@code Flowable} honors the backpressure of the downstream consumer
* and expects the other {@code Publisher} to honor it as well.
* - Scheduler:
* - {@code andThen} does not operate by default on a particular {@link Scheduler}.
*
* @param the value type of the next {@code Publisher}
* @param next the {@code Publisher} to subscribe after this {@code Completable} is completed, not {@code null}
* @return the new {@code Flowable} that composes this {@code Completable} and the next {@code Publisher}
* @throws NullPointerException if {@code next} is {@code null}
*/
@CheckReturnValue
@NonNull
@BackpressureSupport(BackpressureKind.FULL)
@SchedulerSupport(SchedulerSupport.NONE)
public final <@NonNull T> Flowable andThen(@NonNull Publisher next) {
Objects.requireNonNull(next, "next is null");
return RxJavaPlugins.onAssembly(new CompletableAndThenPublisher<>(this, next));
}
/**
* Returns a {@link Single} which will subscribe to this {@code Completable} and once that is completed then
* will subscribe to the {@code next} {@link SingleSource}. An error event from this {@code Completable} will be
* propagated to the downstream observer and will result in skipping the subscription to the next
* {@code SingleSource}.
*
*
*
* - Scheduler:
* - {@code andThen} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the value type of the next {@code SingleSource}
* @param next the {@code SingleSource} to subscribe after this {@code Completable} is completed, not {@code null}
* @return the new {@code Single} that composes this {@code Completable} and the next {@code SingleSource}
* @throws NullPointerException if {@code next} is {@code null}
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public final <@NonNull T> Single andThen(@NonNull SingleSource next) {
Objects.requireNonNull(next, "next is null");
return RxJavaPlugins.onAssembly(new SingleDelayWithCompletable<>(next, this));
}
/**
* Returns a {@link Maybe} which will subscribe to this {@code Completable} and once that is completed then
* will subscribe to the {@code next} {@link MaybeSource}. An error event from this {@code Completable} will be
* propagated to the downstream observer and will result in skipping the subscription to the next
* {@code MaybeSource}.
*
*
*
* - Scheduler:
* - {@code andThen} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the value type of the next {@code MaybeSource}
* @param next the {@code MaybeSource} to subscribe after this {@code Completable} is completed, not {@code null}
* @return the new {@code Maybe} that composes this {@code Completable} and the next {@code MaybeSource}
* @throws NullPointerException if {@code next} is {@code null}
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public final <@NonNull T> Maybe andThen(@NonNull MaybeSource next) {
Objects.requireNonNull(next, "next is null");
return RxJavaPlugins.onAssembly(new MaybeDelayWithCompletable<>(next, this));
}
/**
* Returns a {@code Completable} that first runs this {@code Completable}
* and then the other {@link CompletableSource}. An error event from this {@code Completable} will be
* propagated to the downstream observer and will result in skipping the subscription to the next
* {@code CompletableSource}.
*
*
*
* This is an alias for {@link #concatWith(CompletableSource)}.
*
* - Scheduler:
* - {@code andThen} does not operate by default on a particular {@link Scheduler}.
*
* @param next the other {@code CompletableSource}, not {@code null}
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code next} is {@code null}
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@NonNull
public final Completable andThen(@NonNull CompletableSource next) {
Objects.requireNonNull(next, "next is null");
return RxJavaPlugins.onAssembly(new CompletableAndThenCompletable(this, next));
}
/**
* Subscribes to and awaits the termination of this {@code Completable} instance in a blocking manner and
* rethrows any exception emitted.
*
*
*
* - Scheduler:
* - {@code blockingAwait} does not operate by default on a particular {@link Scheduler}.
* - Error handling:
* - If the source signals an error, the operator wraps a checked {@link Exception}
* into {@link RuntimeException} and throws that. Otherwise, {@code RuntimeException}s and
* {@link Error}s are rethrown as they are.
*
* @throws RuntimeException wrapping an {@link InterruptedException} if the current thread is interrupted
*/
@SchedulerSupport(SchedulerSupport.NONE)
public final void blockingAwait() {
BlockingMultiObserver observer = new BlockingMultiObserver<>();
subscribe(observer);
observer.blockingGet();
}
/**
* Subscribes to and awaits the termination of this {@code Completable} instance in a blocking manner
* with a specific timeout and rethrows any exception emitted within the timeout window.
*
*
*
* - Scheduler:
* - {@code blockingAwait} does not operate by default on a particular {@link Scheduler}.
* - Error handling:
* - If the source signals an error, the operator wraps a checked {@link Exception}
* into {@link RuntimeException} and throws that. Otherwise, {@code RuntimeException}s and
* {@link Error}s are rethrown as they are.
*
* @param timeout the timeout value
* @param unit the timeout unit
* @return {@code true} if the this {@code Completable} instance completed normally within the time limit,
* {@code false} if the timeout elapsed before this {@code Completable} terminated.
* @throws RuntimeException wrapping an {@link InterruptedException} if the current thread is interrupted
* @throws NullPointerException if {@code unit} is {@code null}
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public final boolean blockingAwait(long timeout, @NonNull TimeUnit unit) {
Objects.requireNonNull(unit, "unit is null");
BlockingMultiObserver observer = new BlockingMultiObserver<>();
subscribe(observer);
return observer.blockingAwait(timeout, unit);
}
/**
* Subscribes to the current {@code Completable} and blocks the current thread until it terminates.
*
*
*
* - Scheduler:
* - {@code blockingSubscribe} does not operate by default on a particular {@link Scheduler}.
* - Error handling:
* - If the current {@code Completable} signals an error,
* the {@link Throwable} is routed to the global error handler via {@link RxJavaPlugins#onError(Throwable)}.
* If the current thread is interrupted, an {@link InterruptedException} is routed to the same global error handler.
*
*
* @since 3.0.0
* @see #blockingSubscribe(Action)
* @see #blockingSubscribe(Action, Consumer)
*/
@SchedulerSupport(SchedulerSupport.NONE)
public final void blockingSubscribe() {
blockingSubscribe(Functions.EMPTY_ACTION, Functions.ERROR_CONSUMER);
}
/**
* Subscribes to the current {@code Completable} and calls given {@code onComplete} callback on the current thread
* when it completes normally.
*
*
*
* - Scheduler:
* - {@code blockingSubscribe} does not operate by default on a particular {@link Scheduler}.
* - Error handling:
* - If either the current {@code Completable} signals an error or {@code onComplete} throws,
* the respective {@link Throwable} is routed to the global error handler via {@link RxJavaPlugins#onError(Throwable)}.
* If the current thread is interrupted, an {@link InterruptedException} is routed to the same global error handler.
*
*
* @param onComplete the {@link Action} to call if the current {@code Completable} completes normally
* @throws NullPointerException if {@code onComplete} is {@code null}
* @since 3.0.0
* @see #blockingSubscribe(Action, Consumer)
*/
@SchedulerSupport(SchedulerSupport.NONE)
public final void blockingSubscribe(@NonNull Action onComplete) {
blockingSubscribe(onComplete, Functions.ERROR_CONSUMER);
}
/**
* Subscribes to the current {@code Completable} and calls the appropriate callback on the current thread
* when it terminates.
*
*
*
* - Scheduler:
* - {@code blockingSubscribe} does not operate by default on a particular {@link Scheduler}.
* - Error handling:
* - If either {@code onComplete} or {@code onError} throw, the {@link Throwable} is routed to the
* global error handler via {@link RxJavaPlugins#onError(Throwable)}.
* If the current thread is interrupted, the {@code onError} consumer is called with an {@link InterruptedException}.
*
*
* @param onComplete the {@link Action} to call if the current {@code Completable} completes normally
* @param onError the {@link Consumer} to call if the current {@code Completable} signals an error
* @throws NullPointerException if {@code onComplete} or {@code onError} is {@code null}
* @since 3.0.0
*/
@SchedulerSupport(SchedulerSupport.NONE)
public final void blockingSubscribe(@NonNull Action onComplete, @NonNull Consumer super Throwable> onError) {
Objects.requireNonNull(onComplete, "onComplete is null");
Objects.requireNonNull(onError, "onError is null");
BlockingMultiObserver observer = new BlockingMultiObserver<>();
subscribe(observer);
observer.blockingConsume(Functions.emptyConsumer(), onError, onComplete);
}
/**
* Subscribes to the current {@code Completable} and calls the appropriate {@link CompletableObserver} method on the current thread.
*
*
*
* - Scheduler:
* - {@code blockingSubscribe} does not operate by default on a particular {@link Scheduler}.
* - Error handling:
* - An {@code onError} signal is delivered to the {@link CompletableObserver#onError(Throwable)} method.
* If any of the {@code CompletableObserver}'s methods throw, the {@link RuntimeException} is propagated to the caller of this method.
* If the current thread is interrupted, an {@link InterruptedException} is delivered to {@code observer.onError}.
*
*
* @param observer the {@code CompletableObserver} to call methods on the current thread
* @throws NullPointerException if {@code observer} is {@code null}
* @since 3.0.0
*/
@SchedulerSupport(SchedulerSupport.NONE)
public final void blockingSubscribe(@NonNull CompletableObserver observer) {
Objects.requireNonNull(observer, "observer is null");
BlockingDisposableMultiObserver blockingObserver = new BlockingDisposableMultiObserver<>();
observer.onSubscribe(blockingObserver);
subscribe(blockingObserver);
blockingObserver.blockingConsume(observer);
}
/**
* Subscribes to this {@code Completable} only once, when the first {@link CompletableObserver}
* subscribes to the result {@code Completable}, caches its terminal event
* and relays/replays it to observers.
*
*
*
* Note that this operator doesn't allow disposing the connection
* of the upstream source.
*
* - Scheduler:
* - {@code cache} does not operate by default on a particular {@link Scheduler}.
*
* History: 2.0.4 - experimental
* @return the new {@code Completable} instance
* @since 2.1
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@NonNull
public final Completable cache() {
return RxJavaPlugins.onAssembly(new CompletableCache(this));
}
/**
* Calls the given transformer function with this instance and returns the function's resulting
* {@link CompletableSource} wrapped with {@link #wrap(CompletableSource)}.
*
*
*
* - Scheduler:
* - {@code compose} does not operate by default on a particular {@link Scheduler}.
*
* @param transformer the transformer function, not {@code null}
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code transformer} is {@code null}
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@NonNull
public final Completable compose(@NonNull CompletableTransformer transformer) {
return wrap(Objects.requireNonNull(transformer, "transformer is null").apply(this));
}
/**
* Concatenates this {@code Completable} with another {@link CompletableSource}.
* An error event from this {@code Completable} will be
* propagated to the downstream observer and will result in skipping the subscription to the next
* {@code CompletableSource}.
*
*
*
* - Scheduler:
* - {@code concatWith} does not operate by default on a particular {@link Scheduler}.
*
* @param other the other {@code CompletableSource}, not {@code null}
* @return the new {@code Completable} which subscribes to this and then the other {@code CompletableSource}
* @throws NullPointerException if {@code other} is {@code null}
* @see #andThen(CompletableSource)
* @see #andThen(MaybeSource)
* @see #andThen(ObservableSource)
* @see #andThen(SingleSource)
* @see #andThen(Publisher)
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public final Completable concatWith(@NonNull CompletableSource other) {
Objects.requireNonNull(other, "other is null");
return RxJavaPlugins.onAssembly(new CompletableAndThenCompletable(this, other));
}
/**
* Returns a {@code Completable} which delays the emission of the completion event by the given time.
*
*
*
* - Scheduler:
* - {@code delay} does operate by default on the {@code computation} {@link Scheduler}.
*
* @param time the delay time
* @param unit the delay unit
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code unit} is {@code null}
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.COMPUTATION)
@NonNull
public final Completable delay(long time, @NonNull TimeUnit unit) {
return delay(time, unit, Schedulers.computation(), false);
}
/**
* Returns a {@code Completable} which delays the emission of the completion event by the given time while
* running on the specified {@link Scheduler}.
*
*
*
* - Scheduler:
* - {@code delay} operates on the {@code Scheduler} you specify.
*
* @param time the delay time
* @param unit the delay unit
* @param scheduler the {@code Scheduler} to run the delayed completion on
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code unit} or {@code scheduler} is {@code null}
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.CUSTOM)
@NonNull
public final Completable delay(long time, @NonNull TimeUnit unit, @NonNull Scheduler scheduler) {
return delay(time, unit, scheduler, false);
}
/**
* Returns a {@code Completable} which delays the emission of the completion event, and optionally the error as well, by the given time while
* running on the specified {@link Scheduler}.
*
*
*
* - Scheduler:
* - {@code delay} operates on the {@code Scheduler} you specify.
*
* @param time the delay time
* @param unit the delay unit
* @param scheduler the {@code Scheduler} to run the delayed completion on
* @param delayError delay the error emission as well?
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code unit} or {@code scheduler} is {@code null}
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.CUSTOM)
public final Completable delay(long time, @NonNull TimeUnit unit, @NonNull Scheduler scheduler, boolean delayError) {
Objects.requireNonNull(unit, "unit is null");
Objects.requireNonNull(scheduler, "scheduler is null");
return RxJavaPlugins.onAssembly(new CompletableDelay(this, time, unit, scheduler, delayError));
}
/**
* Returns a {@code Completable} that delays the subscription to the upstream by a given amount of time.
*
*
*
* - Scheduler:
* - This version of {@code delaySubscription} operates by default on the {@code computation} {@link Scheduler}.
*
* History: 2.2.3 - experimental
*
* @param time the time to delay the subscription
* @param unit the time unit of {@code delay}
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code unit} is {@code null}
* @since 3.0.0
* @see ReactiveX operators documentation: Delay
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.COMPUTATION)
@NonNull
public final Completable delaySubscription(long time, @NonNull TimeUnit unit) {
return delaySubscription(time, unit, Schedulers.computation());
}
/**
* Returns a {@code Completable} that delays the subscription to the upstream by a given amount of time,
* both waiting and subscribing on a given {@link Scheduler}.
*
*
*
* - Scheduler:
* - You specify which {@code Scheduler} this operator will use.
*
* History: 2.2.3 - experimental
* @param time the time to delay the subscription
* @param unit the time unit of {@code delay}
* @param scheduler the {@code Scheduler} on which the waiting and subscription will happen
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code unit} or {@code scheduler} is {@code null}
* @since 3.0.0
* @see ReactiveX operators documentation: Delay
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.CUSTOM)
@NonNull
public final Completable delaySubscription(long time, @NonNull TimeUnit unit, @NonNull Scheduler scheduler) {
return Completable.timer(time, unit, scheduler).andThen(this);
}
/**
* Returns a {@code Completable} which calls the given {@code onComplete} {@link Action} if this {@code Completable} completes.
*
*
*
* - Scheduler:
* - {@code doOnComplete} does not operate by default on a particular {@link Scheduler}.
*
* @param onComplete the {@code Action} to call when this emits an {@code onComplete} event
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code onComplete} is {@code null}
* @see #doFinally(Action)
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@NonNull
public final Completable doOnComplete(@NonNull Action onComplete) {
return doOnLifecycle(Functions.emptyConsumer(), Functions.emptyConsumer(),
onComplete, Functions.EMPTY_ACTION,
Functions.EMPTY_ACTION, Functions.EMPTY_ACTION);
}
/**
* Calls the shared {@link Action} if a {@link CompletableObserver} subscribed to the current
* {@code Completable} disposes the common {@link Disposable} it received via {@code onSubscribe}.
*
*
*
* - Scheduler:
* - {@code doOnDispose} does not operate by default on a particular {@link Scheduler}.
*
* @param onDispose the {@code Action} to call when the downstream observer disposes the subscription
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code onDispose} is {@code null}
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@NonNull
public final Completable doOnDispose(@NonNull Action onDispose) {
return doOnLifecycle(Functions.emptyConsumer(), Functions.emptyConsumer(),
Functions.EMPTY_ACTION, Functions.EMPTY_ACTION,
Functions.EMPTY_ACTION, onDispose);
}
/**
* Returns a {@code Completable} which calls the given {@code onError} {@link Consumer} if this {@code Completable} emits an error.
*
*
*
* - Scheduler:
* - {@code doOnError} does not operate by default on a particular {@link Scheduler}.
*
* @param onError the error {@code Consumer} receiving the upstream {@link Throwable} if the upstream signals it via {@code onError}
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code onError} is {@code null}
* @see #doFinally(Action)
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@NonNull
public final Completable doOnError(@NonNull Consumer super Throwable> onError) {
return doOnLifecycle(Functions.emptyConsumer(), onError,
Functions.EMPTY_ACTION, Functions.EMPTY_ACTION,
Functions.EMPTY_ACTION, Functions.EMPTY_ACTION);
}
/**
* Returns a {@code Completable} which calls the given {@code onEvent} {@link Consumer} with the {@link Throwable} for an {@code onError}
* or {@code null} for an {@code onComplete} signal from this {@code Completable} before delivering the signal to the downstream.
*
*
*
* - Scheduler:
* - {@code doOnEvent} does not operate by default on a particular {@link Scheduler}.
*
* @param onEvent the event {@code Consumer} that receives {@code null} for upstream
* completion or a {@code Throwable} if the upstream signaled an error
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code onEvent} is {@code null}
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public final Completable doOnEvent(@NonNull Consumer<@Nullable ? super Throwable> onEvent) {
Objects.requireNonNull(onEvent, "onEvent is null");
return RxJavaPlugins.onAssembly(new CompletableDoOnEvent(this, onEvent));
}
/**
* Calls the appropriate {@code onXXX} method (shared between all {@link CompletableObserver}s) for the lifecycle events of
* the sequence (subscription, disposal).
*
*
*
* - Scheduler:
* - {@code doOnLifecycle} does not operate by default on a particular {@link Scheduler}.
*
*
* @param onSubscribe
* a {@link Consumer} called with the {@link Disposable} sent via {@link CompletableObserver#onSubscribe(Disposable)}
* @param onDispose
* called when the downstream disposes the {@code Disposable} via {@code dispose()}
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code onSubscribe} or {@code onDispose} is {@code null}
* @see ReactiveX operators documentation: Do
* @since 3.0.0
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@NonNull
public final Completable doOnLifecycle(@NonNull Consumer super Disposable> onSubscribe, @NonNull Action onDispose) {
return doOnLifecycle(onSubscribe, Functions.emptyConsumer(),
Functions.EMPTY_ACTION, Functions.EMPTY_ACTION,
Functions.EMPTY_ACTION, onDispose);
}
/**
* Returns a {@code Completable} instance that calls the various callbacks upon the specific
* lifecycle events.
*
* - Scheduler:
* - {@code doOnLifecycle} does not operate by default on a particular {@link Scheduler}.
*
* @param onSubscribe the {@link Consumer} called when a {@link CompletableObserver} subscribes.
* @param onError the {@code Consumer} called when this emits an {@code onError} event
* @param onComplete the {@link Action} called just before when the current {@code Completable} completes normally
* @param onTerminate the {@code Action} called just before this {@code Completable} terminates
* @param onAfterTerminate the {@code Action} called after this {@code Completable} completes normally
* @param onDispose the {@code Action} called when the downstream disposes the subscription
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code onSubscribe}, {@code onError}, {@code onComplete}
* {@code onTerminate}, {@code onAfterTerminate} or {@code onDispose} is {@code null}
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
private Completable doOnLifecycle(
final Consumer super Disposable> onSubscribe,
final Consumer super Throwable> onError,
final Action onComplete,
final Action onTerminate,
final Action onAfterTerminate,
final Action onDispose) {
Objects.requireNonNull(onSubscribe, "onSubscribe is null");
Objects.requireNonNull(onError, "onError is null");
Objects.requireNonNull(onComplete, "onComplete is null");
Objects.requireNonNull(onTerminate, "onTerminate is null");
Objects.requireNonNull(onAfterTerminate, "onAfterTerminate is null");
Objects.requireNonNull(onDispose, "onDispose is null");
return RxJavaPlugins.onAssembly(new CompletablePeek(this, onSubscribe, onError, onComplete, onTerminate, onAfterTerminate, onDispose));
}
/**
* Returns a {@code Completable} instance that calls the given {@code onSubscribe} callback with the disposable
* that the downstream {@link CompletableObserver}s receive upon subscription.
*
*
*
* - Scheduler:
* - {@code doOnSubscribe} does not operate by default on a particular {@link Scheduler}.
*
* @param onSubscribe the {@link Consumer} called when a downstream {@code CompletableObserver} subscribes
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code onSubscribe} is {@code null}
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@NonNull
public final Completable doOnSubscribe(@NonNull Consumer super Disposable> onSubscribe) {
return doOnLifecycle(onSubscribe, Functions.emptyConsumer(),
Functions.EMPTY_ACTION, Functions.EMPTY_ACTION,
Functions.EMPTY_ACTION, Functions.EMPTY_ACTION);
}
/**
* Returns a {@code Completable} instance that calls the given {@code onTerminate} {@link Action} just before this {@code Completable}
* completes normally or with an exception.
*
*
*
* - Scheduler:
* - {@code doOnTerminate} does not operate by default on a particular {@link Scheduler}.
*
* @param onTerminate the {@code Action} to call just before this {@code Completable} terminates
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code onTerminate} is {@code null}
* @see #doFinally(Action)
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@NonNull
public final Completable doOnTerminate(@NonNull Action onTerminate) {
return doOnLifecycle(Functions.emptyConsumer(), Functions.emptyConsumer(),
Functions.EMPTY_ACTION, onTerminate,
Functions.EMPTY_ACTION, Functions.EMPTY_ACTION);
}
/**
* Returns a {@code Completable} instance that calls the given {@code onAfterTerminate} {@link Action} after this {@code Completable}
* completes normally or with an exception.
*
*
*
* - Scheduler:
* - {@code doAfterTerminate} does not operate by default on a particular {@link Scheduler}.
*
* @param onAfterTerminate the {@code Action} to call after this {@code Completable} terminates
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code onAfterTerminate} is {@code null}
* @see #doFinally(Action)
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@NonNull
public final Completable doAfterTerminate(@NonNull Action onAfterTerminate) {
return doOnLifecycle(
Functions.emptyConsumer(),
Functions.emptyConsumer(),
Functions.EMPTY_ACTION,
Functions.EMPTY_ACTION,
onAfterTerminate,
Functions.EMPTY_ACTION);
}
/**
* Calls the specified {@link Action} after this {@code Completable} signals {@code onError} or {@code onComplete} or gets disposed by
* the downstream.
*
*
*
* In case of a race between a terminal event and a dispose call, the provided {@code onFinally} action
* is executed once per subscription.
*
* Note that the {@code onFinally} action is shared between subscriptions and as such
* should be thread-safe.
*
* - Scheduler:
* - {@code doFinally} does not operate by default on a particular {@link Scheduler}.
*
* History: 2.0.1 - experimental
* @param onFinally the {@code Action} called when this {@code Completable} terminates or gets disposed
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code onFinally} is {@code null}
* @since 2.1
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public final Completable doFinally(@NonNull Action onFinally) {
Objects.requireNonNull(onFinally, "onFinally is null");
return RxJavaPlugins.onAssembly(new CompletableDoFinally(this, onFinally));
}
/**
* This method requires advanced knowledge about building operators, please consider
* other standard composition methods first;
* Returns a {@code Completable} which, when subscribed to, invokes the {@link CompletableOperator#apply(CompletableObserver) apply(CompletableObserver)} method
* of the provided {@link CompletableOperator} for each individual downstream {@link Completable} and allows the
* insertion of a custom operator by accessing the downstream's {@link CompletableObserver} during this subscription phase
* and providing a new {@code CompletableObserver}, containing the custom operator's intended business logic, that will be
* used in the subscription process going further upstream.
*
*
*
* Generally, such a new {@code CompletableObserver} will wrap the downstream's {@code CompletableObserver} and forwards the
* {@code onError} and {@code onComplete} events from the upstream directly or according to the
* emission pattern the custom operator's business logic requires. In addition, such operator can intercept the
* flow control calls of {@code dispose} and {@code isDisposed} that would have traveled upstream and perform
* additional actions depending on the same business logic requirements.
*
* Example:
*
* // Step 1: Create the consumer type that will be returned by the CompletableOperator.apply():
*
* public final class CustomCompletableObserver implements CompletableObserver, Disposable {
*
* // The downstream's CompletableObserver that will receive the onXXX events
* final CompletableObserver downstream;
*
* // The connection to the upstream source that will call this class' onXXX methods
* Disposable upstream;
*
* // The constructor takes the downstream subscriber and usually any other parameters
* public CustomCompletableObserver(CompletableObserver downstream) {
* this.downstream = downstream;
* }
*
* // In the subscription phase, the upstream sends a Disposable to this class
* // and subsequently this class has to send a Disposable to the downstream.
* // Note that relaying the upstream's Disposable directly is not allowed in RxJava
* @Override
* public void onSubscribe(Disposable d) {
* if (upstream != null) {
* d.dispose();
* } else {
* upstream = d;
* downstream.onSubscribe(this);
* }
* }
*
* // Some operators may handle the upstream's error while others
* // could just forward it to the downstream.
* @Override
* public void onError(Throwable throwable) {
* downstream.onError(throwable);
* }
*
* // When the upstream completes, usually the downstream should complete as well.
* // In completable, this could also mean doing some side-effects
* @Override
* public void onComplete() {
* System.out.println("Sequence completed");
* downstream.onComplete();
* }
*
* // Some operators may use their own resources which should be cleaned up if
* // the downstream disposes the flow before it completed. Operators without
* // resources can simply forward the dispose to the upstream.
* // In some cases, a disposed flag may be set by this method so that other parts
* // of this class may detect the dispose and stop sending events
* // to the downstream.
* @Override
* public void dispose() {
* upstream.dispose();
* }
*
* // Some operators may simply forward the call to the upstream while others
* // can return the disposed flag set in dispose().
* @Override
* public boolean isDisposed() {
* return upstream.isDisposed();
* }
* }
*
* // Step 2: Create a class that implements the CompletableOperator interface and
* // returns the custom consumer type from above in its apply() method.
* // Such class may define additional parameters to be submitted to
* // the custom consumer type.
*
* final class CustomCompletableOperator implements CompletableOperator {
* @Override
* public CompletableObserver apply(CompletableObserver upstream) {
* return new CustomCompletableObserver(upstream);
* }
* }
*
* // Step 3: Apply the custom operator via lift() in a flow by creating an instance of it
* // or reusing an existing one.
*
* Completable.complete()
* .lift(new CustomCompletableOperator())
* .test()
* .assertResult();
*
*
* Creating custom operators can be complicated and it is recommended one consults the
* RxJava wiki: Writing operators page about
* the tools, requirements, rules, considerations and pitfalls of implementing them.
*
* Note that implementing custom operators via this {@code lift()} method adds slightly more overhead by requiring
* an additional allocation and indirection per assembled flows. Instead, extending the abstract {@code Completable}
* class and creating a {@link CompletableTransformer} with it is recommended.
*
* Note also that it is not possible to stop the subscription phase in {@code lift()} as the {@code apply()} method
* requires a non-{@code null} {@code CompletableObserver} instance to be returned, which is then unconditionally subscribed to
* the current {@code Completable}. For example, if the operator decided there is no reason to subscribe to the
* upstream source because of some optimization possibility or a failure to prepare the operator, it still has to
* return a {@code CompletableObserver} that should immediately dispose the upstream's {@link Disposable} in its
* {@code onSubscribe} method. Again, using a {@code CompletableTransformer} and extending the {@code Completable} is
* a better option as {@link #subscribeActual} can decide to not subscribe to its upstream after all.
*
* - Scheduler:
* - {@code lift} does not operate by default on a particular {@link Scheduler}, however, the
* {@code CompletableOperator} may use a {@code Scheduler} to support its own asynchronous behavior.
*
*
* @param onLift the {@code CompletableOperator} that receives the downstream's {@code CompletableObserver} and should return
* a {@code CompletableObserver} with custom behavior to be used as the consumer for the current
* {@code Completable}.
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code onLift} is {@code null}
* @see RxJava wiki: Writing operators
* @see #compose(CompletableTransformer)
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public final Completable lift(@NonNull CompletableOperator onLift) {
Objects.requireNonNull(onLift, "onLift is null");
return RxJavaPlugins.onAssembly(new CompletableLift(this, onLift));
}
/**
* Maps the signal types of this {@code Completable} into a {@link Notification} of the same kind
* and emits it as a single success value to downstream.
*
*
*
* - Scheduler:
* - {@code materialize} does not operate by default on a particular {@link Scheduler}.
*
* History: 2.2.4 - experimental
* @param the intended target element type of the {@code Notification}
* @return the new {@link Single} instance
* @since 3.0.0
* @see Single#dematerialize(Function)
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@NonNull
public final <@NonNull T> Single> materialize() {
return RxJavaPlugins.onAssembly(new CompletableMaterialize<>(this));
}
/**
* Returns a {@code Completable} which subscribes to this and the other {@link CompletableSource} and completes
* when both of them complete or one emits an error.
*
*
*
* - Scheduler:
* - {@code mergeWith} does not operate by default on a particular {@link Scheduler}.
*
* @param other the other {@code CompletableSource} instance
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code other} is {@code null}
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public final Completable mergeWith(@NonNull CompletableSource other) {
Objects.requireNonNull(other, "other is null");
return mergeArray(this, other);
}
/**
* Returns a {@code Completable} which emits the terminal events from the thread of the specified {@link Scheduler}.
*
*
*
* - Scheduler:
* - {@code observeOn} operates on a {@code Scheduler} you specify.
*
* @param scheduler the {@code Scheduler} to emit terminal events on
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code scheduler} is {@code null}
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.CUSTOM)
public final Completable observeOn(@NonNull Scheduler scheduler) {
Objects.requireNonNull(scheduler, "scheduler is null");
return RxJavaPlugins.onAssembly(new CompletableObserveOn(this, scheduler));
}
/**
* Returns a {@code Completable} instance that if this {@code Completable} emits an error, it will emit an {@code onComplete}
* and swallow the upstream {@link Throwable}.
*
*
*
* - Scheduler:
* - {@code onErrorComplete} does not operate by default on a particular {@link Scheduler}.
*
* @return the new {@code Completable} instance
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@NonNull
public final Completable onErrorComplete() {
return onErrorComplete(Functions.alwaysTrue());
}
/**
* Returns a {@code Completable} instance that if this {@code Completable} emits an error and the {@link Predicate} returns
* {@code true}, it will emit an {@code onComplete} and swallow the {@link Throwable}.
*
*
*
* - Scheduler:
* - {@code onErrorComplete} does not operate by default on a particular {@link Scheduler}.
*
* @param predicate the {@code Predicate} to call when a {@code Throwable} is emitted which should return {@code true}
* if the {@code Throwable} should be swallowed and replaced with an {@code onComplete}.
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code predicate} is {@code null}
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public final Completable onErrorComplete(@NonNull Predicate super Throwable> predicate) {
Objects.requireNonNull(predicate, "predicate is null");
return RxJavaPlugins.onAssembly(new CompletableOnErrorComplete(this, predicate));
}
/**
* Returns a {@code Completable} instance that when encounters an error from this {@code Completable}, calls the
* specified {@code mapper} {@link Function} that returns a {@link CompletableSource} instance for it and resumes the
* execution with it.
*
*
*
* - Scheduler:
* - {@code onErrorResumeNext} does not operate by default on a particular {@link Scheduler}.
*
* @param fallbackSupplier the {@code mapper} {@code Function} that takes the error and should return a {@code CompletableSource} as
* continuation.
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code fallbackSupplier} is {@code null}
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public final Completable onErrorResumeNext(@NonNull Function super Throwable, ? extends CompletableSource> fallbackSupplier) {
Objects.requireNonNull(fallbackSupplier, "fallbackSupplier is null");
return RxJavaPlugins.onAssembly(new CompletableResumeNext(this, fallbackSupplier));
}
/**
* Resumes the flow with the given {@link CompletableSource} when the current {@code Completable} fails instead of
* signaling the error via {@code onError}.
*
*
*
* You can use this to prevent errors from propagating or to supply fallback data should errors be
* encountered.
*
* - Scheduler:
* - {@code onErrorResumeWith} does not operate by default on a particular {@link Scheduler}.
*
*
* @param fallback
* the next {@code CompletableSource} that will take over if the current {@code Completable} encounters
* an error
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code fallback} is {@code null}
* @see ReactiveX operators documentation: Catch
* @since 3.0.0
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public final Completable onErrorResumeWith(@NonNull CompletableSource fallback) {
Objects.requireNonNull(fallback, "fallback is null");
return onErrorResumeNext(Functions.justFunction(fallback));
}
/**
* Ends the flow with a success item returned by a function for the {@link Throwable} error signaled by the current
* {@code Completable} instead of signaling the error via {@code onError}.
*
*
*
* You can use this to prevent errors from propagating or to supply fallback data should errors be
* encountered.
*
* - Scheduler:
* - {@code onErrorReturn} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the item type to return on error
* @param itemSupplier
* a function that returns a single value that will be emitted as success value
* the current {@code Completable} signals an {@code onError} event
* @return the new {@link Maybe} instance
* @throws NullPointerException if {@code itemSupplier} is {@code null}
* @see ReactiveX operators documentation: Catch
* @since 3.0.0
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public final <@NonNull T> Maybe onErrorReturn(@NonNull Function super Throwable, ? extends T> itemSupplier) {
Objects.requireNonNull(itemSupplier, "itemSupplier is null");
return RxJavaPlugins.onAssembly(new CompletableOnErrorReturn<>(this, itemSupplier));
}
/**
* Ends the flow with the given success item when the current {@code Completable}
* fails instead of signaling the error via {@code onError}.
*
*
*
* You can use this to prevent errors from propagating or to supply fallback data should errors be
* encountered.
*
* - Scheduler:
* - {@code onErrorReturnItem} does not operate by default on a particular {@link Scheduler}.
*
*
* @param the item type to return on error
* @param item
* the value that is emitted as {@code onSuccess} in case the current {@code Completable} signals an {@code onError}
* @return the new {@link Maybe} instance
* @throws NullPointerException if {@code item} is {@code null}
* @see ReactiveX operators documentation: Catch
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public final <@NonNull T> Maybe onErrorReturnItem(@NonNull T item) {
Objects.requireNonNull(item, "item is null");
return onErrorReturn(Functions.justFunction(item));
}
/**
* Nulls out references to the upstream producer and downstream {@link CompletableObserver} if
* the sequence is terminated or downstream calls {@code dispose()}.
*
*
*
* - Scheduler:
* - {@code onTerminateDetach} does not operate by default on a particular {@link Scheduler}.
*
* History: 2.1.5 - experimental
* @return the new {@code Completable} instance
* @since 2.2
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@NonNull
public final Completable onTerminateDetach() {
return RxJavaPlugins.onAssembly(new CompletableDetach(this));
}
/**
* Returns a {@code Completable} that repeatedly subscribes to this {@code Completable} until disposed.
*
*
*
* - Scheduler:
* - {@code repeat} does not operate by default on a particular {@link Scheduler}.
*
* @return the new {@code Completable} instance
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@NonNull
public final Completable repeat() {
return fromPublisher(toFlowable().repeat());
}
/**
* Returns a {@code Completable} that subscribes repeatedly at most the given number of times to this {@code Completable}.
*
*
*
* - Scheduler:
* - {@code repeat} does not operate by default on a particular {@link Scheduler}.
*
* @param times the number of times the re-subscription should happen
* @return the new {@code Completable} instance
* @throws IllegalArgumentException if {@code times} is negative
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@NonNull
public final Completable repeat(long times) {
return fromPublisher(toFlowable().repeat(times));
}
/**
* Returns a {@code Completable} that repeatedly subscribes to this {@code Completable} so long as the given
* stop {@link BooleanSupplier} returns {@code false}.
*
*
*
* - Scheduler:
* - {@code repeatUntil} does not operate by default on a particular {@link Scheduler}.
*
* @param stop the {@code BooleanSupplier} that should return {@code true} to stop resubscribing.
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code stop} is {@code null}
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@NonNull
public final Completable repeatUntil(@NonNull BooleanSupplier stop) {
return fromPublisher(toFlowable().repeatUntil(stop));
}
/**
* Returns a {@code Completable} instance that repeats when the {@link Publisher} returned by the handler {@link Function}
* emits an item or completes when this {@code Publisher} emits an {@code onComplete} event.
*
*
*
* - Scheduler:
* - {@code repeatWhen} does not operate by default on a particular {@link Scheduler}.
*
* @param handler the {@code Function} that transforms the stream of values indicating the completion of
* this {@code Completable} and returns a {@code Publisher} that emits items for repeating or completes to indicate the
* repetition should stop
* @return the new {@code Completable} instance
* @throws NullPointerException if {@code handler} is {@code null}
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
@NonNull
public final Completable repeatWhen(@NonNull Function super Flowable