Class FlowControlHandler
java.lang.Object
io.netty.channel.ChannelHandlerAdapter
io.netty.channel.ChannelInboundHandlerAdapter
io.netty.channel.ChannelDuplexHandler
io.netty.handler.flow.FlowControlHandler
- All Implemented Interfaces:
ChannelHandler, ChannelInboundHandler, ChannelOutboundHandler
The
FlowControlHandler ensures that only one message per read() is sent downstream.
Classes such as ByteToMessageDecoder or MessageToByteEncoder are free to emit as
many events as they like for any given input. A channel's auto reading configuration doesn't usually
apply in these scenarios. This is causing problems in downstream ChannelHandlers that would
like to hold subsequent events while they're processing one event. It's a common problem with the
HttpObjectDecoder that will very often fire an HttpRequest that is immediately followed
by a LastHttpContent event.
ChannelPipeline pipeline = ...;
pipeline.addLast(new HttpServerCodec());
pipeline.addLast(new FlowControlHandler());
pipeline.addLast(new MyExampleHandler());
class MyExampleHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
if (msg instanceof HttpRequest) {
ctx.channel().config().setAutoRead(false);
// The FlowControlHandler will hold any subsequent events that
// were emitted by HttpObjectDecoder until auto reading is turned
// back on or Channel#read() is being called.
}
}
}
- See Also:
-
Nested Class Summary
Nested ClassesNested classes/interfaces inherited from interface ChannelHandler
ChannelHandler.Sharable -
Field Summary
FieldsModifier and TypeFieldDescriptionprivate ChannelConfigprivate booleantruewhile adequeue(ChannelHandlerContext)loop is on the stack.private static final InternalLoggerprivate final booleanprivate intNumber of unsatisfied downstreamread()calls. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoidCallsChannelHandlerContext.fireChannelInactive()to forward to the nextChannelInboundHandlerin theChannelPipeline.voidchannelRead(ChannelHandlerContext ctx, Object msg) CallsChannelHandlerContext.fireChannelRead(Object)to forward to the nextChannelInboundHandlerin theChannelPipeline.voidCallsChannelHandlerContext.fireChannelReadComplete()to forward to the nextChannelInboundHandlerin theChannelPipeline.private booleanDequeues messages while auto-read is enabled or downstream reads are unsatisfied, and updatesunsatisfiedReadsaccordingly.private voiddestroy()Releases all messages and destroys theQueue.voidDo nothing by default, sub-classes may override this method.voidDo nothing by default, sub-classes may override this method.(package private) booleanDetermine if the underlyingQueueis empty.voidCallsChannelHandlerContext.read()to forward to the nextChannelOutboundHandlerin theChannelPipeline.Methods inherited from class ChannelDuplexHandler
bind, close, connect, deregister, disconnect, flush, writeMethods inherited from class ChannelInboundHandlerAdapter
channelActive, channelRegistered, channelUnregistered, channelWritabilityChanged, exceptionCaught, userEventTriggeredMethods inherited from class ChannelHandlerAdapter
ensureNotSharable, isSharable
-
Field Details
-
logger
-
releaseMessages
private final boolean releaseMessages -
queue
-
config
-
unsatisfiedReads
private int unsatisfiedReadsNumber of unsatisfied downstreamread()calls. A downstreamread()is considered unsatisfied if auto-read is off and if it has not yet been paired with afireChannelReador a cumulativefireChannelReadComplete.A
read()can be satisfied in three ways, whichever comes first:- inside the
read()call itself, bydequeue()ing a message - in a
channelRead() - in a
channelReadComplete()
read()can be satisfied with auto-read on.When one or more
read()calls are unsatisfied, a downstreamchannelReadCompleteis fired only when either of the following happens:- auto-read is off and
unsatisfiedReadsreturns to zero afterdequeue()ing, or - an upstream
channelReadCompletearrives
- inside the
-
dequeuing
private boolean dequeuingtruewhile adequeue(ChannelHandlerContext)loop is on the stack.
-
-
Constructor Details
-
FlowControlHandler
public FlowControlHandler() -
FlowControlHandler
public FlowControlHandler(boolean releaseMessages)
-
-
Method Details
-
isQueueEmpty
boolean isQueueEmpty()Determine if the underlyingQueueis empty. This method exists for testing, debugging and inspection purposes and it is not Thread safe! -
destroy
private void destroy()Releases all messages and destroys theQueue. -
handlerAdded
Description copied from class:ChannelHandlerAdapterDo nothing by default, sub-classes may override this method.- Specified by:
handlerAddedin interfaceChannelHandler- Overrides:
handlerAddedin classChannelHandlerAdapter- Throws:
Exception
-
handlerRemoved
Description copied from class:ChannelHandlerAdapterDo nothing by default, sub-classes may override this method.- Specified by:
handlerRemovedin interfaceChannelHandler- Overrides:
handlerRemovedin classChannelHandlerAdapter- Throws:
Exception
-
channelInactive
Description copied from class:ChannelInboundHandlerAdapterCallsChannelHandlerContext.fireChannelInactive()to forward to the nextChannelInboundHandlerin theChannelPipeline. Sub-classes may override this method to change behavior.- Specified by:
channelInactivein interfaceChannelInboundHandler- Overrides:
channelInactivein classChannelInboundHandlerAdapter- Throws:
Exception
-
read
Description copied from class:ChannelDuplexHandlerCallsChannelHandlerContext.read()to forward to the nextChannelOutboundHandlerin theChannelPipeline. Sub-classes may override this method to change behavior.- Specified by:
readin interfaceChannelOutboundHandler- Overrides:
readin classChannelDuplexHandler- Throws:
Exception
-
channelRead
Description copied from class:ChannelInboundHandlerAdapterCallsChannelHandlerContext.fireChannelRead(Object)to forward to the nextChannelInboundHandlerin theChannelPipeline. Sub-classes may override this method to change behavior.- Specified by:
channelReadin interfaceChannelInboundHandler- Overrides:
channelReadin classChannelInboundHandlerAdapter- Throws:
Exception
-
channelReadComplete
Description copied from class:ChannelInboundHandlerAdapterCallsChannelHandlerContext.fireChannelReadComplete()to forward to the nextChannelInboundHandlerin theChannelPipeline. Sub-classes may override this method to change behavior.- Specified by:
channelReadCompletein interfaceChannelInboundHandler- Overrides:
channelReadCompletein classChannelInboundHandlerAdapter- Throws:
Exception
-
dequeue
Dequeues messages while auto-read is enabled or downstream reads are unsatisfied, and updatesunsatisfiedReadsaccordingly.- See Also:
-