T
- the value typepublic final class ReplayProcessor<T> extends FlowableProcessor<T>
The ReplayProcessor can be created in bounded and unbounded mode. It can be bounded by size (maximum number of elements retained at most) and/or time (maximum age of elements replayed).
This Processor respects the backpressure behavior of its Subscribers (individually) but does not coordinate their request amounts towards the upstream (because there might not be any).
Note that Subscribers receive a continuous sequence of values after they subscribed even if an individual item gets delayed due to backpressure.
Example usage:
ReplayProcessor<Object> processor = new ReplayProcessor<T>();
processor.onNext("one");
processor.onNext("two");
processor.onNext("three");
processor.onComplete();
// both of the following will get the onNext/onComplete calls from above
processor.subscribe(subscriber1);
processor.subscribe(subscriber2);
Modifier and Type | Method and Description |
---|---|
static <T> ReplayProcessor<T> |
create()
Creates an unbounded ReplayProcessor.
|
static <T> ReplayProcessor<T> |
create(int capacityHint)
Creates an unbounded ReplayProcessor with the specified initial buffer capacity.
|
static <T> ReplayProcessor<T> |
createWithSize(int maxSize)
Creates a size-bounded ReplayProcessor.
|
static <T> ReplayProcessor<T> |
createWithTime(long maxAge,
java.util.concurrent.TimeUnit unit,
Scheduler scheduler)
Creates a time-bounded ReplayProcessor.
|
static <T> ReplayProcessor<T> |
createWithTimeAndSize(long maxAge,
java.util.concurrent.TimeUnit unit,
Scheduler scheduler,
int maxSize)
Creates a time- and size-bounded ReplayProcessor.
|
java.lang.Throwable |
getThrowable()
Returns the error that caused the Subject to terminate or null if the Subject
hasn't terminated yet.
|
T |
getValue()
Returns a single value the Subject currently has or null if no such value exists.
|
java.lang.Object[] |
getValues()
Returns an Object array containing snapshot all values of the Subject.
|
T[] |
getValues(T[] array)
Returns a typed array containing a snapshot of all values of the Subject.
|
boolean |
hasComplete()
Returns true if the subject has reached a terminal state through a complete event.
|
boolean |
hasSubscribers()
Returns true if the subject has subscribers.
|
boolean |
hasThrowable()
Returns true if the subject has reached a terminal state through an error event.
|
boolean |
hasValue()
Returns true if the subject has any value.
|
void |
onComplete() |
void |
onError(java.lang.Throwable t) |
void |
onNext(T t) |
void |
onSubscribe(org.reactivestreams.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(org.reactivestreams.Subscriber<? super T> s)
Operator implementations (both source and intermediate) should implement this method that
performs the necessary business logic.
|
toSerialized
all, amb, ambArray, ambWith, any, blockingFirst, blockingFirst, blockingForEach, blockingIterable, blockingIterable, blockingLast, blockingLast, blockingLatest, blockingMostRecent, blockingNext, blockingSingle, blockingSingle, blockingSubscribe, blockingSubscribe, blockingSubscribe, blockingSubscribe, blockingSubscribe, buffer, buffer, buffer, buffer, buffer, buffer, buffer, buffer, buffer, buffer, buffer, buffer, buffer, buffer, buffer, buffer, buffer, buffer, buffer, bufferSize, cache, cacheWithInitialCapacity, cast, collect, collectInto, combineLatest, combineLatest, combineLatest, combineLatest, combineLatest, combineLatest, combineLatest, combineLatest, combineLatest, combineLatest, combineLatest, combineLatest, combineLatest, combineLatestDelayError, combineLatestDelayError, combineLatestDelayError, combineLatestDelayError, combineLatestDelayError, combineLatestDelayError, compose, concat, concat, concat, concat, concat, concat, concatArray, concatArrayDelayError, concatArrayEager, concatArrayEager, concatDelayError, concatDelayError, concatDelayError, concatEager, concatEager, concatEager, concatEager, concatMap, concatMap, concatMapDelayError, concatMapDelayError, concatMapEager, concatMapEager, concatMapEagerDelayError, concatMapEagerDelayError, concatMapIterable, concatMapIterable, concatWith, contains, count, create, 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, flatMap, flatMap, flatMap, flatMap, flatMap, flatMap, flatMap, flatMap, flatMap, flatMap, flatMap, flatMap, flatMapCompletable, flatMapCompletable, flatMapIterable, flatMapIterable, flatMapIterable, flatMapIterable, flatMapMaybe, flatMapMaybe, flatMapSingle, flatMapSingle, forEach, forEachWhile, forEachWhile, forEachWhile, fromArray, fromCallable, fromFuture, fromFuture, fromFuture, fromFuture, fromIterable, fromPublisher, generate, generate, generate, generate, generate, 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, lift, map, materialize, merge, merge, merge, merge, merge, merge, merge, merge, mergeArray, mergeArray, mergeArrayDelayError, mergeArrayDelayError, mergeDelayError, mergeDelayError, mergeDelayError, mergeDelayError, mergeDelayError, mergeDelayError, mergeDelayError, mergeDelayError, mergeWith, never, observeOn, observeOn, observeOn, ofType, onBackpressureBuffer, onBackpressureBuffer, onBackpressureBuffer, onBackpressureBuffer, onBackpressureBuffer, onBackpressureBuffer, onBackpressureBuffer, onBackpressureBuffer, onBackpressureDrop, onBackpressureDrop, onBackpressureLatest, onErrorResumeNext, onErrorResumeNext, onErrorReturn, onErrorReturnItem, onExceptionResumeNext, 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, retry, retry, retry, retry, retry, retryUntil, retryWhen, safeSubscribe, sample, sample, sample, sample, sample, sample, scan, scan, scanWith, sequenceEqual, sequenceEqual, sequenceEqual, sequenceEqual, serialize, share, single, singleElement, singleOrError, skip, skip, skip, skipLast, skipLast, skipLast, skipLast, skipLast, skipLast, skipUntil, skipWhile, sorted, sorted, startWith, startWith, startWith, startWithArray, strict, subscribe, subscribe, subscribe, subscribe, subscribe, subscribe, subscribe, subscribeOn, subscribeWith, switchIfEmpty, switchMap, switchMap, switchMapDelayError, switchMapDelayError, switchOnNext, switchOnNext, switchOnNextDelayError, switchOnNextDelayError, take, take, take, takeLast, takeLast, takeLast, takeLast, takeLast, takeLast, takeLast, takeLast, takeLast, takeUntil, takeUntil, takeWhile, test, test, test, throttleFirst, throttleFirst, throttleLast, throttleLast, 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, window, window, withLatestFrom, withLatestFrom, withLatestFrom, withLatestFrom, withLatestFrom, withLatestFrom, zip, zip, zip, zip, zip, zip, zip, zip, zip, zip, zip, zip, zipArray, zipIterable, zipWith, zipWith, zipWith, zipWith
@CheckReturnValue public static <T> ReplayProcessor<T> create()
The internal buffer is backed by an ArrayList
and starts with an initial capacity of 16. Once the
number of items reaches this capacity, it will grow as necessary (usually by 50%). However, as the
number of items grows, this causes frequent array reallocation and copying, and may hurt performance
and latency. This can be avoided with the create(int)
overload which takes an initial capacity
parameter and can be tuned to reduce the array reallocation frequency as needed.
T
- the type of items observed and emitted by the ReplayProcessor@CheckReturnValue public static <T> ReplayProcessor<T> create(int capacityHint)
Use this method to avoid excessive array reallocation while the internal buffer grows to accommodate new
items. For example, if you know that the buffer will hold 32k items, you can ask the
ReplayProcessor
to preallocate its internal array with a capacity to hold that many items. Once
the items start to arrive, the internal array won't need to grow, creating less garbage and no overhead
due to frequent array-copying.
T
- the type of items observed and emitted by the SubjectcapacityHint
- the initial buffer capacity@CheckReturnValue public static <T> ReplayProcessor<T> createWithSize(int maxSize)
In this setting, the ReplayProcessor
holds at most size
items in its internal buffer and
discards the oldest item.
When observers subscribe to a terminated ReplayProcessor
, they are guaranteed to see at most
size
onNext
events followed by a termination event.
If an observer subscribes while the ReplayProcessor
is active, it will observe all items in the
buffer at that point in time and each item observed afterwards, even if the buffer evicts items due to
the size constraint in the mean time. In other words, once an Observer subscribes, it will receive items
without gaps in the sequence.
T
- the type of items observed and emitted by the SubjectmaxSize
- the maximum number of buffered items@CheckReturnValue public static <T> ReplayProcessor<T> createWithTime(long maxAge, java.util.concurrent.TimeUnit unit, Scheduler scheduler)
In this setting, the ReplayProcessor
internally tags each observed item with a timestamp value
supplied by the Scheduler
and keeps only those whose age is less than the supplied time value
converted to milliseconds. For example, an item arrives at T=0 and the max age is set to 5; at T>=5
this first item is then evicted by any subsequent item or termination event, leaving the buffer empty.
Once the subject is terminated, observers subscribing to it will receive items that remained in the buffer after the terminal event, regardless of their age.
If an observer subscribes while the ReplayProcessor
is active, it will observe only those items
from within the buffer that have an age less than the specified time, and each item observed thereafter,
even if the buffer evicts items due to the time constraint in the mean time. In other words, once an
observer subscribes, it observes items without gaps in the sequence except for any outdated items at the
beginning of the sequence.
Note that terminal notifications (onError
and onComplete
) trigger eviction as well. For
example, with a max age of 5, the first item is observed at T=0, then an onComplete
notification
arrives at T=10. If an observer subscribes at T=11, it will find an empty ReplayProcessor
with just
an onComplete
notification.
T
- the type of items observed and emitted by the SubjectmaxAge
- the maximum age of the contained itemsunit
- the time unit of time
scheduler
- the Scheduler
that provides the current time@CheckReturnValue public static <T> ReplayProcessor<T> createWithTimeAndSize(long maxAge, java.util.concurrent.TimeUnit unit, Scheduler scheduler, int maxSize)
In this setting, the ReplayProcessor
internally tags each received item with a timestamp value
supplied by the Scheduler
and holds at most size
items in its internal buffer. It evicts
items from the start of the buffer if their age becomes less-than or equal to the supplied age in
milliseconds or the buffer reaches its size
limit.
When observers subscribe to a terminated ReplayProcessor
, they observe the items that remained in
the buffer after the terminal notification, regardless of their age, but at most size
items.
If an observer subscribes while the ReplayProcessor
is active, it will observe only those items
from within the buffer that have age less than the specified time and each subsequent item, even if the
buffer evicts items due to the time constraint in the mean time. In other words, once an observer
subscribes, it observes items without gaps in the sequence except for the outdated items at the beginning
of the sequence.
Note that terminal notifications (onError
and onComplete
) trigger eviction as well. For
example, with a max age of 5, the first item is observed at T=0, then an onComplete
notification
arrives at T=10. If an observer subscribes at T=11, it will find an empty ReplayProcessor
with just
an onComplete
notification.
T
- the type of items observed and emitted by the SubjectmaxAge
- the maximum age of the contained itemsunit
- the time unit of time
maxSize
- the maximum number of buffered itemsscheduler
- the Scheduler
that provides the current timeprotected void subscribeActual(org.reactivestreams.Subscriber<? super T> s)
Flowable
There is no need to call any of the plugin hooks on the current Flowable instance or the Subscriber.
subscribeActual
in class Flowable<T>
s
- the incoming Subscriber, never nullpublic void onSubscribe(org.reactivestreams.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 onNext(T t)
public void onError(java.lang.Throwable t)
public void onComplete()
public boolean hasSubscribers()
FlowableProcessor
The method is thread-safe.
hasSubscribers
in class FlowableProcessor<T>
public java.lang.Throwable getThrowable()
FlowableProcessor
The method is thread-safe.
getThrowable
in class FlowableProcessor<T>
public T getValue()
The method is thread-safe.
public java.lang.Object[] getValues()
The method is thread-safe.
public T[] getValues(T[] array)
The method follows the conventions of Collection.toArray by setting the array element after the last value to null (if the capacity permits).
The method is thread-safe.
array
- the target array to copy values into if it fitspublic boolean hasComplete()
FlowableProcessor
The method is thread-safe.
hasComplete
in class FlowableProcessor<T>
FlowableProcessor.hasThrowable()
public boolean hasThrowable()
FlowableProcessor
The method is thread-safe.
hasThrowable
in class FlowableProcessor<T>
FlowableProcessor.getThrowable()
,
FlowableProcessor.hasComplete()
public boolean hasValue()
The method is thread-safe.