Class JerseyPublisher<T>
- java.lang.Object
-
- org.glassfish.jersey.internal.util.JerseyPublisher<T>
-
- All Implemented Interfaces:
Flow.Publisher<T>
public class JerseyPublisher<T> extends java.lang.Object implements Flow.Publisher<T>
Implementation ofFlow.Publisher
corresponding to reactive streams specification.Delegates to
SubmissionPublisher
repackaged from jsr166.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
JerseyPublisher.PublisherStrategy
static class
JerseyPublisher.SubscriberWrapper<T>
-
Field Summary
Fields Modifier and Type Field Description private static int
DEFAULT_BUFFER_CAPACITY
private JerseyPublisher.PublisherStrategy
strategy
private SubmissionPublisher<T>
submissionPublisher
-
Constructor Summary
Constructors Constructor Description JerseyPublisher()
Creates a new JerseyPublisher using theForkJoinPool.commonPool()
for async delivery to subscribers (unless it does not support a parallelism level of at least two, in which case, a new Thread is created to run each task), with maximum buffer capacity of 256 and defaultJerseyPublisher.PublisherStrategy
, which isJerseyPublisher.PublisherStrategy.BEST_EFFORT
.JerseyPublisher(int maxBufferCapacity)
Creates a new JerseyPublisher using theForkJoinPool.commonPool()
for async delivery to subscribers (unless it does not support a parallelism level of at least two, in which case, a new Thread is created to run each task), with specified maximum buffer capacity and defaultJerseyPublisher.PublisherStrategy
, which isJerseyPublisher.PublisherStrategy.BEST_EFFORT
.JerseyPublisher(java.util.concurrent.Executor executor)
Creates a new JerseyPublisher using the givenExecutor
for async delivery to subscribers, with the default maximum buffer size of 256 and defaultJerseyPublisher.PublisherStrategy
, which isJerseyPublisher.PublisherStrategy.BEST_EFFORT
.JerseyPublisher(java.util.concurrent.Executor executor, int maxBufferCapacity, JerseyPublisher.PublisherStrategy strategy)
Creates a new JerseyPublisher using the givenExecutor
for async delivery to subscribers, with the given maximum buffer size for each subscriber and givenJerseyPublisher.PublisherStrategy
.JerseyPublisher(java.util.concurrent.Executor executor, JerseyPublisher.PublisherStrategy strategy)
Creates a new JerseyPublisher using the givenExecutor
for async delivery to subscribers, with the default maximum buffer size of 256 and givenJerseyPublisher.PublisherStrategy
.JerseyPublisher(JerseyPublisher.PublisherStrategy strategy)
Creates a new JerseyPublisher using theForkJoinPool.commonPool()
for async delivery to subscribers (unless it does not support a parallelism level of at least two, in which case, a new Thread is created to run each task), with maximum buffer capacity of 256 and givenJerseyPublisher.PublisherStrategy
.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description void
close()
Unless already closed, issuesonComplete()
signals to current subscribers, and disallows subsequent attempts to publish.void
closeExceptionally(java.lang.Throwable error)
Issues onError signals to current subscribers with the given error, and disallows subsequent attempts to publish.java.util.concurrent.CompletableFuture<java.lang.Void>
consume(java.util.function.Consumer<? super T> consumer)
Processes all published items using the given Consumer function.int
estimateMaximumLag()
Returns an estimate of the maximum number of items produced but not yet consumed among all current subscribers.long
estimateMinimumDemand()
Returns an estimate of the minimum number of items requested but not yet produced, among all current subscribers.java.lang.Throwable
getClosedException()
Returns the exception associated withcloseExceptionally(java.lang.Throwable)
, or null if not closed or if closed normally.int
getMaxBufferCapacity()
Returns the maximum per-subscriber buffer capacity.private JerseyPublisher.SubscriberWrapper
getSubscriberWrapper(Flow.Subscriber subscriber)
private int
offer(T item, long timeout, java.util.concurrent.TimeUnit unit, java.util.function.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.private int
offer(T item, java.util.function.BiPredicate<Flow.Subscriber<? super T>,? super T> onDrop)
Publishes the given item, if possible, to each current subscriber by asynchronously invoking itsonNext
method.private boolean
onDrop(Flow.Subscriber<? super T> subscriber, T t)
int
publish(T item)
Publishes the given item to all current subscribers by invoking itsonNext() method
usingExecutor
provided as constructor parameter (or the defaultExecutor
if not provided).private int
submit(T data)
Publishes the given item to each current subscriber by asynchronously invoking its onNext method.void
subscribe(Flow.Subscriber<? super T> subscriber)
Adds the given Subscriber if possible.
-
-
-
Field Detail
-
DEFAULT_BUFFER_CAPACITY
private static final int DEFAULT_BUFFER_CAPACITY
- See Also:
- Constant Field Values
-
submissionPublisher
private SubmissionPublisher<T> submissionPublisher
-
strategy
private final JerseyPublisher.PublisherStrategy strategy
-
-
Constructor Detail
-
JerseyPublisher
public JerseyPublisher()
Creates a new JerseyPublisher using theForkJoinPool.commonPool()
for async delivery to subscribers (unless it does not support a parallelism level of at least two, in which case, a new Thread is created to run each task), with maximum buffer capacity of 256 and defaultJerseyPublisher.PublisherStrategy
, which isJerseyPublisher.PublisherStrategy.BEST_EFFORT
.
-
JerseyPublisher
public JerseyPublisher(JerseyPublisher.PublisherStrategy strategy)
Creates a new JerseyPublisher using theForkJoinPool.commonPool()
for async delivery to subscribers (unless it does not support a parallelism level of at least two, in which case, a new Thread is created to run each task), with maximum buffer capacity of 256 and givenJerseyPublisher.PublisherStrategy
.- Parameters:
strategy
- publisher delivering strategy
-
JerseyPublisher
public JerseyPublisher(java.util.concurrent.Executor executor)
Creates a new JerseyPublisher using the givenExecutor
for async delivery to subscribers, with the default maximum buffer size of 256 and defaultJerseyPublisher.PublisherStrategy
, which isJerseyPublisher.PublisherStrategy.BEST_EFFORT
.- Parameters:
executor
-Executor
the executor to use for async delivery, supporting creation of at least one independent thread- Throws:
java.lang.NullPointerException
- if executor is nulljava.lang.IllegalArgumentException
- if maxBufferCapacity not positive
-
JerseyPublisher
public JerseyPublisher(java.util.concurrent.Executor executor, JerseyPublisher.PublisherStrategy strategy)
Creates a new JerseyPublisher using the givenExecutor
for async delivery to subscribers, with the default maximum buffer size of 256 and givenJerseyPublisher.PublisherStrategy
.- Parameters:
executor
-Executor
the executor to use for async delivery, supporting creation of at least one independent threadstrategy
- publisher delivering strategy- Throws:
java.lang.NullPointerException
- if executor is nulljava.lang.IllegalArgumentException
- if maxBufferCapacity not positive
-
JerseyPublisher
public JerseyPublisher(int maxBufferCapacity)
Creates a new JerseyPublisher using theForkJoinPool.commonPool()
for async delivery to subscribers (unless it does not support a parallelism level of at least two, in which case, a new Thread is created to run each task), with specified maximum buffer capacity and defaultJerseyPublisher.PublisherStrategy
, which isJerseyPublisher.PublisherStrategy.BEST_EFFORT
.- Parameters:
maxBufferCapacity
- the maximum capacity for each subscriber's buffer (the enforced capacity may be rounded up to the nearest power of two and/or bounded by the largest value supported by this implementation; methodgetMaxBufferCapacity()
returns the actual value)
-
JerseyPublisher
public JerseyPublisher(java.util.concurrent.Executor executor, int maxBufferCapacity, JerseyPublisher.PublisherStrategy strategy)
Creates a new JerseyPublisher using the givenExecutor
for async delivery to subscribers, with the given maximum buffer size for each subscriber and givenJerseyPublisher.PublisherStrategy
.- Parameters:
executor
-Executor
the executor to use for async delivery, supporting creation of at least one independent threadmaxBufferCapacity
- the maximum capacity for each subscriber's buffer (the enforced capacity may be rounded up to the nearest power of two and/or bounded by the largest value supported by this implementation; methodgetMaxBufferCapacity()
returns the actual value)strategy
- publisher delivering strategy- Throws:
java.lang.NullPointerException
- if executor is nulljava.lang.IllegalArgumentException
- if maxBufferCapacity not positive
-
-
Method Detail
-
subscribe
public void subscribe(Flow.Subscriber<? super T> subscriber)
Description copied from interface:Flow.Publisher
Adds the given Subscriber if possible. If already subscribed, or the attempt to subscribe fails due to policy violations or errors, the Subscriber'sonError
method is invoked with anIllegalStateException
. Otherwise, the Subscriber'sonSubscribe
method is invoked with a newFlow.Subscription
. Subscribers may enable receiving items by invoking therequest
method of this Subscription, and may unsubscribe by invoking itscancel
method.- Specified by:
subscribe
in interfaceFlow.Publisher<T>
- Parameters:
subscriber
- the subscriber
-
submit
private int submit(T data)
Publishes the given item to each current subscriber by asynchronously invoking its onNext method.Blocks uninterruptibly while resources for any subscriber are unavailable.
- Parameters:
data
- published data- Returns:
- the estimated maximum lag among subscribers
- Throws:
java.lang.IllegalStateException
- if closedjava.lang.NullPointerException
- if data is nulljava.util.concurrent.RejectedExecutionException
- if thrown by Executor
-
consume
public java.util.concurrent.CompletableFuture<java.lang.Void> consume(java.util.function.Consumer<? super T> consumer)
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
- function to process all published data- Returns:
- a
CompletableFuture
that is completed normally when the publisher signals onComplete, and exceptionally upon any error or cancellation - Throws:
java.lang.NullPointerException
- if consumer is null
-
offer
private int offer(T item, java.util.function.BiPredicate<Flow.Subscriber<? super T>,? super T> onDrop)
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:
java.lang.IllegalStateException
- if closedjava.lang.NullPointerException
- if item is nulljava.util.concurrent.RejectedExecutionException
- if thrown by Executor
-
offer
private int offer(T item, long timeout, java.util.concurrent.TimeUnit unit, java.util.function.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:
java.lang.IllegalStateException
- if closedjava.lang.NullPointerException
- if item is nulljava.util.concurrent.RejectedExecutionException
- if thrown by Executor
-
onDrop
private boolean onDrop(Flow.Subscriber<? super T> subscriber, T t)
-
getSubscriberWrapper
private JerseyPublisher.SubscriberWrapper getSubscriberWrapper(Flow.Subscriber subscriber)
-
publish
public int publish(T item)
Publishes the given item to all current subscribers by invoking itsonNext() method
usingExecutor
provided as constructor parameter (or the defaultExecutor
if not provided).Concrete behaviour is specified by
JerseyPublisher.PublisherStrategy
selected uponJerseyPublisher
creation.- Parameters:
item
- the (non-null) item to publish.- Returns:
- if negative, the (negative) number of drops; otherwise an estimate of maximum lag.
- Throws:
java.lang.IllegalStateException
- if closedjava.lang.NullPointerException
- if item is nulljava.util.concurrent.RejectedExecutionException
- if thrown byExecutor
-
close
public 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.
-
closeExceptionally
public void closeExceptionally(java.lang.Throwable error)
Issues onError signals to current subscribers with the given error, and disallows subsequent attempts to publish.- Parameters:
error
- theonError
argument sent to subscribers- Throws:
java.lang.NullPointerException
- if error is null
-
estimateMaximumLag
public int estimateMaximumLag()
Returns an estimate of the maximum number of items produced but not yet consumed among all current subscribers.- Returns:
- estimated maximum lag
-
estimateMinimumDemand
public long estimateMinimumDemand()
Returns an estimate of the minimum number of items requested but not yet produced, among all current subscribers.- Returns:
- estimated minimum demand
-
getClosedException
public java.lang.Throwable getClosedException()
Returns the exception associated withcloseExceptionally(java.lang.Throwable)
, or null if not closed or if closed normally.- Returns:
- exception thrown on closing or
null
-
getMaxBufferCapacity
public int getMaxBufferCapacity()
Returns the maximum per-subscriber buffer capacity.- Returns:
- the maximum per-subscriber buffer capacity
-
-