Class PublishProcessor<T>
- Type Parameters:
T
- the value type multicasted to Subscribers.
- All Implemented Interfaces:
FlowableSubscriber<T>
,org.reactivestreams.Processor<T,
,T> org.reactivestreams.Publisher<T>
,org.reactivestreams.Subscriber<T>
Subscriber
s.
This processor does not have a public constructor by design; a new empty instance of this
PublishProcessor
can be created via the create()
method.
Since a PublishProcessor
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.
PublishProcessor
is a Flowable
as well as a FlowableProcessor
,
however, it does not coordinate backpressure between different subscribers and between an
upstream source and a subscriber. If an upstream item is received via onNext(Object)
, if
a subscriber is not ready to receive an item, that subscriber is terminated via a MissingBackpressureException
.
To avoid this case, use offer(Object)
and retry sometime later if it returned false.
The PublishProcessor
's Subscriber
-side consumes items in an unbounded manner.
For a multicasting processor type that also coordinates between the downstream Subscriber
s and the upstream
source as well, consider using MulticastProcessor
.
When this PublishProcessor
is terminated via onError(Throwable)
or onComplete()
,
late Subscriber
s only receive the respective terminal event.
Unlike a BehaviorProcessor
, a PublishProcessor
doesn't retain/cache items, therefore, a new
Subscriber
won't receive any past items.
Even though PublishProcessor
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 PublishProcessor
reached its terminal state will result in the
given Subscription
being canceled immediately.
Calling onNext(Object)
, offer(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).
Note that serializing over offer(Object)
is not supported through toSerialized()
because it is a method
available on the PublishProcessor
and BehaviorProcessor
classes only.
This PublishProcessor
supports the standard state-peeking methods hasComplete()
, hasThrowable()
,
getThrowable()
and hasSubscribers()
.
- Backpressure:
- The processor does not coordinate backpressure for its subscribers and implements a weaker
onSubscribe
which calls requestsLong.MAX_VALUE
from the incoming Subscriptions. This makes it possible to subscribe thePublishProcessor
to multiple sources (note on serialization though) unlike the standardSubscriber
contract. Child subscribers, however, are not overflown but receive anIllegalStateException
in case their requested amount is zero. - Scheduler:
PublishProcessor
does not operate by default on a particularScheduler
and theSubscriber
s get notified on the thread the respectiveonXXX
methods were invoked.- Error handling:
- When the
onError(Throwable)
is called, thePublishProcessor
enters into a terminal state and emits the sameThrowable
instance to the last set ofSubscriber
s. During this emission, if one or moreSubscriber
s cancel their respectiveSubscription
s, theThrowable
is delivered to the global error handler viaRxJavaPlugins.onError(Throwable)
(multiple times if multipleSubscriber
s cancel at once). If there were noSubscriber
s subscribed to thisPublishProcessor
when theonError()
was called, the global error handler is not invoked.
PublishProcessor<Object> processor = PublishProcessor.create();
// subscriber1 will receive all onNext and onComplete events
processor.subscribe(subscriber1);
processor.onNext("one");
processor.onNext("two");
// subscriber2 will only receive "three" and onComplete
processor.subscribe(subscriber2);
processor.onNext("three");
processor.onComplete();
- See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescription(package private) static final class
Wraps the actual subscriber, tracks its requests and makes cancellation to remove itself from the current subscribers array. -
Field Summary
FieldsModifier and TypeFieldDescription(package private) static final PublishProcessor.PublishSubscription[]
An empty subscribers array to avoid allocating it all the time.(package private) Throwable
The error, write before terminating and read after checking subscribers.(package private) final AtomicReference
<PublishProcessor.PublishSubscription<T>[]> The array of currently subscribed subscribers.(package private) static final PublishProcessor.PublishSubscription[]
The terminated indicator for the subscribers array. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescription(package private) boolean
Tries to add the given subscriber to the subscribers array atomically or returns false if this processor has terminated.static <T> @NonNull PublishProcessor
<T> create()
Constructs a PublishProcessor.Returns the error that caused the FlowableProcessor to terminate or null if the FlowableProcessor hasn't terminated yet.boolean
Returns true if the FlowableProcessor has reached a terminal state through a complete event.boolean
Returns true if the FlowableProcessor has subscribers.boolean
Returns true if the FlowableProcessor has reached a terminal state through an error event.boolean
Tries to emit the item to all currently subscribedSubscriber
s if all of them has requested some value, returnsfalse
otherwise.void
void
void
void
onSubscribe
(@NonNull org.reactivestreams.Subscription s) Implementors of this method should make sure everything that needs to be visible inSubscriber.onNext(Object)
is established before callingSubscription.request(long)
.(package private) void
Atomically removes the given subscriber if it is subscribed to this processor.protected void
subscribeActual
(@NonNull org.reactivestreams.Subscriber<? super @NonNull T> t) Operator implementations (both source and intermediate) should implement this method that performs the necessary business logic and handles the incomingSubscriber
s.Methods inherited from class io.reactivex.rxjava3.processors.FlowableProcessor
toSerialized
Methods inherited from class io.reactivex.rxjava3.core.Flowable
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
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
Methods inherited from interface org.reactivestreams.Publisher
subscribe
-
Field Details
-
TERMINATED
The terminated indicator for the subscribers array. -
EMPTY
An empty subscribers array to avoid allocating it all the time. -
subscribers
The array of currently subscribed subscribers. -
error
Throwable errorThe error, write before terminating and read after checking subscribers.
-
-
Constructor Details
-
PublishProcessor
PublishProcessor()Constructs a PublishProcessor.- Since:
- 2.0
-
-
Method Details
-
create
Constructs a PublishProcessor.- Type Parameters:
T
- the value type- Returns:
- the new PublishProcessor
-
subscribeActual
protected void subscribeActual(@NonNull @NonNull org.reactivestreams.Subscriber<? super @NonNull T> t) Description copied from class:Flowable
Operator implementations (both source and intermediate) should implement this method that performs the necessary business logic and handles the incomingSubscriber
s.There is no need to call any of the plugin hooks on the current
Flowable
instance or theSubscriber
; all hooks and basic safeguards have been applied byFlowable.subscribe(Subscriber)
before this method gets called.- Specified by:
subscribeActual
in classFlowable<T>
- Parameters:
t
- the incomingSubscriber
, nevernull
-
add
Tries to add the given subscriber to the subscribers array atomically or returns false if this processor has terminated.- Parameters:
ps
- the subscriber to add- Returns:
- true if successful, false if this processor has terminated
-
remove
Atomically removes the given subscriber if it is subscribed to this processor.- Parameters:
ps
- the subscription wrapping a subscriber to remove
-
onSubscribe
Description copied from interface:FlowableSubscriber
Implementors of this method should make sure everything that needs to be visible inSubscriber.onNext(Object)
is established before callingSubscription.request(long)
. In practice this means no initialization should happen after therequest()
call and additional behavior is thread safe in respect toonNext
. -
onNext
-
onError
-
onComplete
public void onComplete() -
offer
Tries to emit the item to all currently subscribedSubscriber
s if all of them has requested some value, returnsfalse
otherwise.This method should be called in a sequential manner just like the
onXXX
methods of thisPublishProcessor
.History: 2.0.8 - experimental
- Parameters:
t
- the item to emit, notnull
- Returns:
true
if the item was emitted to allSubscriber
s- Throws:
NullPointerException
- ift
isnull
- Since:
- 2.2
-
hasSubscribers
Description copied from class:FlowableProcessor
Returns true if the FlowableProcessor has subscribers.The method is thread-safe.
- Specified by:
hasSubscribers
in classFlowableProcessor<T>
- Returns:
- true if the FlowableProcessor has subscribers
-
getThrowable
Description copied from class:FlowableProcessor
Returns the error that caused the FlowableProcessor to terminate or null if the FlowableProcessor hasn't terminated yet.The method is thread-safe.
- Specified by:
getThrowable
in classFlowableProcessor<T>
- Returns:
- the error that caused the FlowableProcessor to terminate or null if the FlowableProcessor hasn't terminated yet
-
hasThrowable
Description copied from class:FlowableProcessor
Returns true if the FlowableProcessor has reached a terminal state through an error event.The method is thread-safe.
- Specified by:
hasThrowable
in classFlowableProcessor<T>
- Returns:
- true if the FlowableProcessor has reached a terminal state through an error event
- See Also:
-
hasComplete
Description copied from class:FlowableProcessor
Returns true if the FlowableProcessor has reached a terminal state through a complete event.The method is thread-safe.
- Specified by:
hasComplete
in classFlowableProcessor<T>
- Returns:
- true if the FlowableProcessor has reached a terminal state through a complete event
- See Also:
-