public abstract class AbstractListenerReadPublisher<T>
extends java.lang.Object
Publisher
implementations that bridge between
event-listener read APIs and Reactive Streams.
Specifically a base class for reading from the HTTP request body with Servlet 3.1 non-blocking I/O and Undertow XNIO as well as handling incoming WebSocket messages with standard Java WebSocket (JSR-356), Jetty, and Undertow.
Modifier and Type | Class and Description |
---|---|
private class |
AbstractListenerReadPublisher.ReadSubscription
Subscription that delegates signals to State.
|
private static class |
AbstractListenerReadPublisher.State
Represents a state for the
Publisher to be in. |
Modifier and Type | Field and Description |
---|---|
private boolean |
completionBeforeDemand |
private long |
demand |
private static java.util.concurrent.atomic.AtomicLongFieldUpdater<AbstractListenerReadPublisher> |
DEMAND_FIELD_UPDATER |
private java.lang.Throwable |
errorBeforeDemand |
protected Log |
logger |
private java.util.concurrent.atomic.AtomicReference<AbstractListenerReadPublisher.State> |
state |
private <any> |
subscriber |
Constructor and Description |
---|
AbstractListenerReadPublisher() |
Modifier and Type | Method and Description |
---|---|
private boolean |
changeState(AbstractListenerReadPublisher.State oldState,
AbstractListenerReadPublisher.State newState) |
private void |
changeToDemandState(AbstractListenerReadPublisher.State oldState) |
protected abstract void |
checkOnDataAvailable()
Check if data is available and either call
onDataAvailable()
immediately or schedule a notification. |
private Subscription |
createSubscription() |
void |
onAllDataRead()
Sub-classes can call this method to delegate a contain notification when
all data has been read.
|
void |
onDataAvailable()
Invoked when reading is possible, either in the same thread after a check
via
checkOnDataAvailable() , or as a callback from the underlying
container. |
void |
onError(java.lang.Throwable ex)
Sub-classes can call this to delegate container error notifications.
|
protected abstract T |
read()
Read once from the input, if possible.
|
private boolean |
readAndPublish()
Read and publish data one at a time until there is no more data, no more
demand, or perhaps we completed in the mean time.
|
protected abstract void |
readingPaused()
Invoked when reading is paused due to a lack of demand.
|
void |
subscribe(<any> subscriber) |
protected final Log logger
private final java.util.concurrent.atomic.AtomicReference<AbstractListenerReadPublisher.State> state
private volatile long demand
private static final java.util.concurrent.atomic.AtomicLongFieldUpdater<AbstractListenerReadPublisher> DEMAND_FIELD_UPDATER
@Nullable private volatile <any> subscriber
private volatile boolean completionBeforeDemand
@Nullable private volatile java.lang.Throwable errorBeforeDemand
public void subscribe(<any> subscriber)
public final void onDataAvailable()
checkOnDataAvailable()
, or as a callback from the underlying
container.public void onAllDataRead()
public final void onError(java.lang.Throwable ex)
protected abstract void checkOnDataAvailable()
onDataAvailable()
immediately or schedule a notification.@Nullable protected abstract T read() throws java.io.IOException
null
java.io.IOException
protected abstract void readingPaused()
Note: This method is guaranteed not to compete with
checkOnDataAvailable()
so it can be used to safely suspend
reading, if the underlying API supports it, i.e. without competing with
an implicit call to resume via checkOnDataAvailable()
.
private boolean readAndPublish() throws java.io.IOException
true
if there is more demand; false
if there is
no more demand or we have completed.java.io.IOException
private boolean changeState(AbstractListenerReadPublisher.State oldState, AbstractListenerReadPublisher.State newState)
private void changeToDemandState(AbstractListenerReadPublisher.State oldState)
private Subscription createSubscription()