T
- the value typepublic final class AsyncProcessor<T> extends FlowableProcessor<T>
Subscriber
s.
This processor does not have a public constructor by design; a new empty instance of this
AsyncProcessor
can be created via the create()
method.
Since an AsyncProcessor
is a Reactive Streams Processor
type,
null
s are not allowed (Rule 2.13)
as parameters to onNext(Object)
and onError(Throwable)
. Such calls will result in a
NullPointerException
being thrown and the processor's state is not changed.
AsyncProcessor
is a Flowable
as well as a FlowableProcessor
and supports backpressure from the downstream but
its Subscriber
-side consumes items in an unbounded manner.
When this AsyncProcessor
is terminated via onError(Throwable)
, the
last observed item (if any) is cleared and late Subscriber
s only receive
the onError
event.
The AsyncProcessor
caches the latest item internally and it emits this item only when onComplete
is called.
Therefore, it is not recommended to use this Processor
with infinite or never-completing sources.
Even though AsyncProcessor
implements the Subscriber
interface, calling
onSubscribe
is not required (Rule 2.12)
if the processor is used as a standalone source. However, calling onSubscribe
after the AsyncProcessor
reached its terminal state will result in the
given Subscription
being canceled immediately.
Calling onNext(Object)
, onError(Throwable)
and onComplete()
is required to be serialized (called from the same thread or called non-overlappingly from different threads
through external means of serialization). The FlowableProcessor.toSerialized()
method available to all FlowableProcessor
s
provides such serialization and also protects against reentrance (i.e., when a downstream Subscriber
consuming this processor also wants to call onNext(Object)
on this processor recursively).
The implementation of onXXX
methods are technically thread-safe but non-serialized calls
to them may lead to undefined state in the currently subscribed Subscriber
s.
This AsyncProcessor
supports the standard state-peeking methods hasComplete()
, hasThrowable()
,
getThrowable()
and hasSubscribers()
as well as means to read the very last observed value -
after this AsyncProcessor
has been completed - in a non-blocking and thread-safe
manner via hasValue()
or getValue()
.
AsyncProcessor
honors the backpressure of the downstream Subscriber
s and won't emit
its single value to a particular Subscriber
until that Subscriber
has requested an item.
When the AsyncProcessor
is subscribed to a Flowable
, the processor consumes this
Flowable
in an unbounded manner (requesting Long.MAX_VALUE
) as only the very last upstream item is
retained by it.
AsyncProcessor
does not operate by default on a particular Scheduler
and
the Subscriber
s get notified on the thread where the terminating onError
or onComplete
methods were invoked.onError(Throwable)
is called, the AsyncProcessor
enters into a terminal state
and emits the same Throwable
instance to the last set of Subscriber
s. During this emission,
if one or more Subscriber
s dispose their respective Subscription
s, the
Throwable
is delivered to the global error handler via
RxJavaPlugins.onError(Throwable)
(multiple times if multiple Subscriber
s
cancel at once).
If there were no Subscriber
s subscribed to this AsyncProcessor
when the onError()
was called, the global error handler is not invoked.
Example usage:
AsyncProcessor<Object> processor = AsyncProcessor.create();
TestSubscriber<Object> ts1 = processor.test();
ts1.assertEmpty();
processor.onNext(1);
// AsyncProcessor only emits when onComplete was called.
ts1.assertEmpty();
processor.onNext(2);
processor.onComplete();
// onComplete triggers the emission of the last cached item and the onComplete event.
ts1.assertResult(2);
TestSubscriber<Object> ts2 = processor.test();
// late Subscribers receive the last cached item too
ts2.assertResult(2);
Modifier and Type | Method and Description |
---|---|
static <T> @NonNull AsyncProcessor<T> |
create()
Creates a new AsyncProcessor.
|
@Nullable Throwable |
getThrowable()
Returns the error that caused the FlowableProcessor to terminate or null if the FlowableProcessor
hasn't terminated yet.
|
T |
getValue()
Returns a single value this processor currently has or null if no such value exists.
|
boolean |
hasComplete()
Returns true if the FlowableProcessor has reached a terminal state through a complete event.
|
boolean |
hasSubscribers()
Returns true if the FlowableProcessor has subscribers.
|
boolean |
hasThrowable()
Returns true if the FlowableProcessor has reached a terminal state through an error event.
|
boolean |
hasValue()
Returns true if this processor has any value.
|
void |
onComplete() |
void |
onError(@NonNull Throwable t) |
void |
onNext(T t) |
void |
onSubscribe(@NonNull Subscription s)
Implementors of this method should make sure everything that needs
to be visible in
Subscriber.onNext(Object) is established before
calling Subscription.request(long) . |
protected void |
subscribeActual(@NonNull Subscriber<? super T> s)
Operator implementations (both source and intermediate) should implement this method that
performs the necessary business logic and handles the incoming
Subscriber s. |
toSerialized
all, amb, ambArray, ambWith, any, blockingFirst, blockingFirst, blockingForEach, blockingForEach, blockingIterable, blockingIterable, blockingLast, blockingLast, blockingLatest, blockingMostRecent, blockingNext, blockingSingle, blockingSingle, blockingStream, blockingStream, blockingSubscribe, blockingSubscribe, blockingSubscribe, blockingSubscribe, blockingSubscribe, blockingSubscribe, blockingSubscribe, blockingSubscribe, buffer, buffer, buffer, buffer, buffer, buffer, buffer, buffer, buffer, buffer, buffer, buffer, buffer, buffer, buffer, buffer, buffer, bufferSize, cache, cacheWithInitialCapacity, cast, collect, collect, collectInto, combineLatest, combineLatest, combineLatest, combineLatest, combineLatest, combineLatest, combineLatest, combineLatest, combineLatest, combineLatest, combineLatestArray, combineLatestArray, combineLatestArrayDelayError, combineLatestArrayDelayError, combineLatestDelayError, combineLatestDelayError, compose, concat, concat, concat, concat, concat, concat, concatArray, concatArrayDelayError, concatArrayEager, concatArrayEager, concatArrayEagerDelayError, concatArrayEagerDelayError, concatDelayError, concatDelayError, concatDelayError, concatEager, concatEager, concatEager, concatEager, concatEagerDelayError, concatEagerDelayError, concatEagerDelayError, concatEagerDelayError, concatMap, concatMap, concatMap, concatMapCompletable, concatMapCompletable, concatMapCompletableDelayError, concatMapCompletableDelayError, concatMapCompletableDelayError, concatMapDelayError, concatMapDelayError, concatMapDelayError, concatMapEager, concatMapEager, concatMapEagerDelayError, concatMapEagerDelayError, concatMapIterable, concatMapIterable, concatMapMaybe, concatMapMaybe, concatMapMaybeDelayError, concatMapMaybeDelayError, concatMapMaybeDelayError, concatMapSingle, concatMapSingle, concatMapSingleDelayError, concatMapSingleDelayError, concatMapSingleDelayError, concatMapStream, concatMapStream, concatWith, concatWith, concatWith, concatWith, contains, count, create, debounce, debounce, debounce, debounce, defaultIfEmpty, defer, delay, delay, delay, delay, delay, delay, delaySubscription, delaySubscription, delaySubscription, dematerialize, distinct, distinct, distinct, distinctUntilChanged, distinctUntilChanged, distinctUntilChanged, doAfterNext, doAfterTerminate, doFinally, doOnCancel, doOnComplete, doOnEach, doOnEach, doOnError, doOnLifecycle, doOnNext, doOnRequest, doOnSubscribe, doOnTerminate, elementAt, elementAt, elementAtOrError, empty, error, error, filter, first, firstElement, firstOrError, firstOrErrorStage, firstStage, flatMap, flatMap, flatMap, flatMap, flatMap, flatMap, flatMap, flatMap, flatMap, flatMap, flatMap, flatMap, flatMapCompletable, flatMapCompletable, flatMapIterable, flatMapIterable, flatMapIterable, flatMapIterable, flatMapMaybe, flatMapMaybe, flatMapSingle, flatMapSingle, flatMapStream, flatMapStream, forEach, forEachWhile, forEachWhile, forEachWhile, fromAction, fromArray, fromCallable, fromCompletable, fromCompletionStage, fromFuture, fromFuture, fromIterable, fromMaybe, fromObservable, fromOptional, fromPublisher, fromRunnable, fromSingle, fromStream, fromSupplier, generate, generate, generate, generate, generate, groupBy, groupBy, groupBy, groupBy, groupBy, groupBy, groupJoin, hide, ignoreElements, interval, interval, interval, interval, intervalRange, intervalRange, isEmpty, join, just, just, just, just, just, just, just, just, just, just, last, lastElement, lastOrError, lastOrErrorStage, lastStage, lift, map, mapOptional, materialize, merge, merge, merge, merge, merge, merge, merge, merge, mergeArray, mergeArray, mergeArrayDelayError, mergeArrayDelayError, mergeDelayError, mergeDelayError, mergeDelayError, mergeDelayError, mergeDelayError, mergeDelayError, mergeDelayError, mergeDelayError, mergeWith, mergeWith, mergeWith, mergeWith, never, observeOn, observeOn, observeOn, ofType, onBackpressureBuffer, onBackpressureBuffer, onBackpressureBuffer, onBackpressureBuffer, onBackpressureBuffer, onBackpressureBuffer, onBackpressureBuffer, onBackpressureBuffer, onBackpressureBuffer, onBackpressureBuffer, onBackpressureDrop, onBackpressureDrop, onBackpressureLatest, onBackpressureLatest, onBackpressureReduce, onBackpressureReduce, onErrorComplete, onErrorComplete, onErrorResumeNext, onErrorResumeWith, onErrorReturn, onErrorReturnItem, onTerminateDetach, parallel, parallel, parallel, publish, publish, publish, publish, range, rangeLong, rebatchRequests, reduce, reduce, reduceWith, repeat, repeat, repeatUntil, repeatWhen, replay, replay, replay, replay, replay, replay, replay, replay, replay, replay, replay, replay, replay, replay, replay, replay, replay, replay, retry, retry, retry, retry, retry, retryUntil, retryWhen, safeSubscribe, sample, sample, sample, sample, sample, sample, sample, scan, scan, scanWith, sequenceEqual, sequenceEqual, sequenceEqual, sequenceEqual, serialize, share, single, singleElement, singleOrError, singleOrErrorStage, singleStage, skip, skip, skip, skipLast, skipLast, skipLast, skipLast, skipLast, skipLast, skipUntil, skipWhile, sorted, sorted, startWith, startWith, startWith, startWith, startWithArray, startWithItem, startWithIterable, subscribe, subscribe, subscribe, subscribe, subscribe, subscribe, subscribe, subscribeOn, subscribeOn, subscribeWith, switchIfEmpty, switchMap, switchMap, switchMapCompletable, switchMapCompletableDelayError, switchMapDelayError, switchMapDelayError, switchMapMaybe, switchMapMaybeDelayError, switchMapSingle, switchMapSingleDelayError, switchOnNext, switchOnNext, switchOnNextDelayError, switchOnNextDelayError, take, take, take, takeLast, takeLast, takeLast, takeLast, takeLast, takeLast, takeLast, takeLast, takeLast, takeUntil, takeUntil, takeWhile, test, test, test, throttleFirst, throttleFirst, throttleFirst, throttleLast, throttleLast, throttleLast, throttleLatest, throttleLatest, throttleLatest, throttleLatest, throttleLatest, throttleWithTimeout, throttleWithTimeout, throttleWithTimeout, timeInterval, timeInterval, timeInterval, timeInterval, timeout, timeout, timeout, timeout, timeout, timeout, timeout, timeout, timer, timer, timestamp, timestamp, timestamp, timestamp, to, toFuture, toList, toList, toList, toMap, toMap, toMap, toMultimap, toMultimap, toMultimap, toMultimap, toObservable, toSortedList, toSortedList, toSortedList, toSortedList, unsafeCreate, unsubscribeOn, using, using, window, window, window, window, window, window, window, window, window, window, window, window, window, window, window, window, window, withLatestFrom, withLatestFrom, withLatestFrom, withLatestFrom, withLatestFrom, withLatestFrom, zip, zip, zip, zip, zip, zip, zip, zip, zip, zip, zip, zip, zipArray, zipWith, zipWith, zipWith, zipWith
@CheckReturnValue @NonNull public static <T> @NonNull AsyncProcessor<T> create()
T
- the value type to be received and emittedpublic void onSubscribe(@NonNull Subscription s)
FlowableSubscriber
Subscriber.onNext(Object)
is established before
calling Subscription.request(long)
. In practice this means
no initialization should happen after the request()
call and
additional behavior is thread safe in respect to onNext
.
public void onComplete()
@CheckReturnValue public boolean hasSubscribers()
FlowableProcessor
The method is thread-safe.
hasSubscribers
in class FlowableProcessor<T>
@CheckReturnValue public boolean hasThrowable()
FlowableProcessor
The method is thread-safe.
hasThrowable
in class FlowableProcessor<T>
FlowableProcessor.getThrowable()
,
FlowableProcessor.hasComplete()
@CheckReturnValue public boolean hasComplete()
FlowableProcessor
The method is thread-safe.
hasComplete
in class FlowableProcessor<T>
FlowableProcessor.hasThrowable()
@Nullable @CheckReturnValue public @Nullable Throwable getThrowable()
FlowableProcessor
The method is thread-safe.
getThrowable
in class FlowableProcessor<T>
protected void subscribeActual(@NonNull Subscriber<? super T> s)
Flowable
Subscriber
s.
There is no need to call any of the plugin hooks on the current Flowable
instance or
the Subscriber
; all hooks and basic safeguards have been
applied by Flowable.subscribe(Subscriber)
before this method gets called.
subscribeActual
in class Flowable<T>
s
- the incoming Subscriber
, never null
@CheckReturnValue public boolean hasValue()
The method is thread-safe.
@Nullable @CheckReturnValue public T getValue()
The method is thread-safe.