Interface SubmittableFlowPublisher<T>
- Type Parameters:
T
- the published item type
- All Superinterfaces:
AutoCloseable
,Flow.Publisher<T>
- All Known Implementing Classes:
SubmissionPublisher
Flow.Publisher
that asynchronously issues submitted
(non-null) items to current subscribers until it is closed. Each
current subscriber receives newly submitted items in the same order
unless drops or exceptions are encountered. Using a
SubmittableFlowPublisher allows item generators to act as compliant reactive-streams
Publishers relying on drop handling and/or blocking for flow
control.
An implementation of SubmittableFlowPublisher uses the Executor
supplied in its
constructor for delivery to subscribers. The best choice of
Executor depends on expected usage. If the generator(s) of
submitted items run in separate threads, and the number of
subscribers can be estimated, consider using a Executors.newFixedThreadPool(int)
. Otherwise consider using the
default, normally the ForkJoinPool.commonPool()
.
Buffering allows producers and consumers to transiently operate
at different rates. Each subscriber uses an independent buffer.
Buffers are created upon first use and expanded as needed up to the
given maximum. (The enforced capacity may be rounded up to the
nearest power of two and/or bounded by the largest value supported
by this implementation.) Invocations of request
do not directly result in
buffer expansion, but risk saturation if unfilled requests exceed
the maximum capacity. The default value of Flow.defaultBufferSize()
may provide a useful starting point for
choosing a capacity based on expected rates, resources, and usages.
Publication methods support different policies about what to do
when buffers are saturated. Method submit
blocks until resources are available. This is simplest, but least
responsive. The offer
methods may drop items (either
immediately or with bounded timeout), but provide an opportunity to
interpose a handler and then retry.
If any Subscriber method throws an exception, its subscription
is cancelled. If a handler is supplied as a constructor argument,
it is invoked before cancellation upon an exception in method
onNext
, but exceptions in methods
onSubscribe
,
onError
and
onComplete
are not recorded or
handled before cancellation. If the supplied Executor throws
RejectedExecutionException
(or any other RuntimeException
or Error) when attempting to execute a task, or a drop handler
throws an exception when processing a dropped item, then the
exception is rethrown. In these cases, not all subscribers will
have been issued the published item. It is usually good practice to
closeExceptionally
in these cases.
Method consume(Consumer)
simplifies support for a
common case in which the only action of a subscriber is to request
and process all items using a supplied function.
-
Method Summary
Modifier and TypeMethodDescriptionvoid
close()
Unless already closed, issuesonComplete
signals to current subscribers, and disallows subsequent attempts to publish.void
closeExceptionally
(Throwable error) Unless already closed, issuesonError
signals to current subscribers with the given error, and disallows subsequent attempts to publish.Processes all published items using the given Consumer function.int
Returns an estimate of the maximum number of items produced but not yet consumed among all current subscribers.long
Returns an estimate of the minimum number of items requested (viarequest
) but not yet produced, among all current subscribers.Returns the exception associated withcloseExceptionally
, or null if not closed or if closed normally.int
Returns the maximum per-subscriber buffer capacity.int
offer
(T item, long timeout, TimeUnit unit, BiPredicate<Flow.Subscriber<? super T>, ? super T> onDrop) Publishes the given item, if possible, to each current subscriber by asynchronously invoking itsonNext
method, blocking while resources for any subscription are unavailable, up to the specified timeout or until the caller thread is interrupted, at which point the given handler (if non-null) is invoked, and if it returns true, retried once.int
offer
(T item, BiPredicate<Flow.Subscriber<? super T>, ? super T> onDrop) Publishes the given item, if possible, to each current subscriber by asynchronously invoking itsonNext
method.int
Publishes the given item to each current subscriber by asynchronously invoking itsonNext
method, blocking uninterruptibly while resources for any subscriber are unavailable.void
subscribe
(Flow.Subscriber<? super T> subscriber) Adds the given Subscriber unless already subscribed.
-
Method Details
-
consume
Processes all published items using the given Consumer function. Returns a CompletableFuture that is completed normally when this publisher signalsonComplete
, or completed exceptionally upon any error, or an exception is thrown by the Consumer, or the returned CompletableFuture is cancelled, in which case no further items are processed.- Parameters:
consumer
- the function applied to each onNext item- Returns:
- a CompletableFuture that is completed normally when the publisher signals onComplete, and exceptionally upon any error or cancellation
- Throws:
NullPointerException
- if consumer is null
-
close
void close()Unless already closed, issuesonComplete
signals to current subscribers, and disallows subsequent attempts to publish. Upon return, this method does NOT guarantee that all subscribers have yet completed.- Specified by:
close
in interfaceAutoCloseable
-
closeExceptionally
Unless already closed, issuesonError
signals to current subscribers with the given error, and disallows subsequent attempts to publish. Future subscribers also receive the given error. Upon return, this method does NOT guarantee that all subscribers have yet completed.- Parameters:
error
- theonError
argument sent to subscribers- Throws:
NullPointerException
- if error is null
-
estimateMinimumDemand
long estimateMinimumDemand()Returns an estimate of the minimum number of items requested (viarequest
) but not yet produced, among all current subscribers.- Returns:
- the estimate, or zero if no subscribers
-
estimateMaximumLag
int estimateMaximumLag()Returns an estimate of the maximum number of items produced but not yet consumed among all current subscribers.- Returns:
- the estimate
-
getClosedException
Throwable getClosedException()Returns the exception associated withcloseExceptionally
, or null if not closed or if closed normally.- Returns:
- the exception, or null if none
-
getMaxBufferCapacity
int getMaxBufferCapacity()Returns the maximum per-subscriber buffer capacity.- Returns:
- the maximum per-subscriber buffer capacity
-
offer
int offer(T item, long timeout, TimeUnit unit, BiPredicate<Flow.Subscriber<? super T>, ? super T> onDrop) Publishes the given item, if possible, to each current subscriber by asynchronously invoking itsonNext
method, blocking while resources for any subscription are unavailable, up to the specified timeout or until the caller thread is interrupted, at which point the given handler (if non-null) is invoked, and if it returns true, retried once. (The drop handler may distinguish timeouts from interrupts by checking whether the current thread is interrupted.) Other calls to methods in this class by other threads are blocked while the handler is invoked. Unless recovery is assured, options are usually limited to logging the error and/or issuing anonError
signal to the subscriber.This method returns a status indicator: If negative, it represents the (negative) number of drops (failed attempts to issue the item to a subscriber). Otherwise it is an estimate of the maximum lag (number of items submitted but not yet consumed) among all current subscribers. This value is at least one (accounting for this submitted item) if there are any subscribers, else zero.
If the Executor for this publisher throws a RejectedExecutionException (or any other RuntimeException or Error) when attempting to asynchronously notify subscribers, or the drop handler throws an exception when processing a dropped item, then this exception is rethrown.
- Parameters:
item
- the (non-null) item to publishtimeout
- how long to wait for resources for any subscriber before giving up, in units ofunit
unit
- aTimeUnit
determining how to interpret thetimeout
parameteronDrop
- if non-null, the handler invoked upon a drop to a subscriber, with arguments of the subscriber and item; if it returns true, an offer is re-attempted (once)- Returns:
- if negative, the (negative) number of drops; otherwise an estimate of maximum lag
- Throws:
IllegalStateException
- if closedNullPointerException
- if item is nullRejectedExecutionException
- if thrown by Executor
-
offer
Publishes the given item, if possible, to each current subscriber by asynchronously invoking itsonNext
method. The item may be dropped by one or more subscribers if resource limits are exceeded, in which case the given handler (if non-null) is invoked, and if it returns true, retried once. Other calls to methods in this class by other threads are blocked while the handler is invoked. Unless recovery is assured, options are usually limited to logging the error and/or issuing anonError
signal to the subscriber.This method returns a status indicator: If negative, it represents the (negative) number of drops (failed attempts to issue the item to a subscriber). Otherwise it is an estimate of the maximum lag (number of items submitted but not yet consumed) among all current subscribers. This value is at least one (accounting for this submitted item) if there are any subscribers, else zero.
If the Executor for this publisher throws a RejectedExecutionException (or any other RuntimeException or Error) when attempting to asynchronously notify subscribers, or the drop handler throws an exception when processing a dropped item, then this exception is rethrown.
- Parameters:
item
- the (non-null) item to publishonDrop
- if non-null, the handler invoked upon a drop to a subscriber, with arguments of the subscriber and item; if it returns true, an offer is re-attempted (once)- Returns:
- if negative, the (negative) number of drops; otherwise an estimate of maximum lag
- Throws:
IllegalStateException
- if closedNullPointerException
- if item is nullRejectedExecutionException
- if thrown by Executor
-
submit
Publishes the given item to each current subscriber by asynchronously invoking itsonNext
method, blocking uninterruptibly while resources for any subscriber are unavailable. This method returns an estimate of the maximum lag (number of items submitted but not yet consumed) among all current subscribers. This value is at least one (accounting for this submitted item) if there are any subscribers, else zero.If the Executor for this publisher throws a RejectedExecutionException (or any other RuntimeException or Error) when attempting to asynchronously notify subscribers, then this exception is rethrown, in which case not all subscribers will have been issued this item.
- Parameters:
item
- the (non-null) item to publish- Returns:
- the estimated maximum lag among subscribers
- Throws:
IllegalStateException
- if closedNullPointerException
- if item is nullRejectedExecutionException
- if thrown by Executor
-
subscribe
Adds the given Subscriber unless already subscribed. If already subscribed, the Subscriber'sonError
method is invoked on the existing subscription with anIllegalStateException
. Otherwise, upon success, the Subscriber'sonSubscribe
method is invoked asynchronously with a newFlow.Subscription
. IfonSubscribe
throws an exception, the subscription is cancelled. Otherwise, if this SubmittableFlowPublisher was closed exceptionally, then the subscriber'sonError
method is invoked with the corresponding exception, or if closed without exception, the subscriber'sonComplete
method is invoked. Subscribers may enable receiving items by invoking therequest
method of the new Subscription, and may unsubscribe by invoking itscancel
method.- Specified by:
subscribe
in interfaceFlow.Publisher<T>
- Parameters:
subscriber
- the subscriber- Throws:
NullPointerException
- if subscriber is null
-