Package org.apache.cassandra.transport
Class CQLMessageHandler<M extends Message>
- java.lang.Object
-
- io.netty.channel.ChannelHandlerAdapter
-
- io.netty.channel.ChannelInboundHandlerAdapter
-
- org.apache.cassandra.net.AbstractMessageHandler
-
- org.apache.cassandra.transport.CQLMessageHandler<M>
-
- All Implemented Interfaces:
io.netty.channel.ChannelHandler
,io.netty.channel.ChannelInboundHandler
,FrameDecoder.FrameProcessor
public class CQLMessageHandler<M extends Message> extends AbstractMessageHandler
Implementation ofAbstractMessageHandler
for processing CQL messages which comprise aMessage
wrapped in anEnvelope
. This class is parameterized by aMessage
subtype, expected to be eitherMessage.Request
orMessage.Response
. Most commonly, an instance for handlingMessage.Request
is created for each inbound CQL client connection. # Small vs large messages Small messages are deserialized in place, and then handed off to a consumer for processing. Large messages accumulate frames until all bytes for the envelope are received, then concatenate and deserialize the frames on the event loop thread and pass them on to the same consumer. # Flow control (backpressure) The size of an incoming message is explicit in theEnvelope.Header
. By default, every connection has 1MiB of exlusive permits available before needing to access the per-endpoint and global reserves. By default, those reserves are sized proportionally to the heap - 2.5% of heap per-endpoint and a 10% for the global reserve. Permits are held while CQL messages are processed and released after the response has been encoded into the buffers of the response frame. A connection level option (THROW_ON_OVERLOAD) allows clients to choose the backpressure strategy when a connection has exceeded the maximum number of allowed permits. The choices are to either pause reads from the incoming socket and allow TCP backpressure to do the work, or to throw an explict exception and rely on the client to back off.
-
-
Nested Class Summary
-
Nested classes/interfaces inherited from class org.apache.cassandra.net.AbstractMessageHandler
AbstractMessageHandler.OnHandlerClosed, AbstractMessageHandler.WaitQueue
-
-
Field Summary
Fields Modifier and Type Field Description static int
LARGE_MESSAGE_THRESHOLD
static java.util.concurrent.TimeUnit
RATE_LIMITER_DELAY_UNIT
-
Fields inherited from class org.apache.cassandra.net.AbstractMessageHandler
channel, corruptFramesRecovered, corruptFramesUnrecovered, decoder, endpointReserveCapacity, endpointWaitQueue, globalReserveCapacity, globalWaitQueue, largeMessage, largeThreshold, onClosed, queueCapacity, receivedBytes, receivedCount, throttledCount, throttledNanos
-
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description static OverloadedException
buildOverloadedException(java.util.function.Supplier<java.lang.String> endpointLimits, NonBlockingRateLimiter requestRateLimiter, ClientResourceLimits.Overload overload)
static OverloadedException
buildOverloadedException(ResourceLimits.Limit endpointReserve, ResourceLimits.Limit globalReserve, NonBlockingRateLimiter requestRateLimiter, ClientResourceLimits.Overload overload)
protected void
fatalExceptionCaught(java.lang.Throwable cause)
protected java.lang.String
id()
boolean
process(FrameDecoder.Frame frame)
Frame processor that the frames should be handed off to.protected void
processCorruptFrame(FrameDecoder.CorruptFrame frame)
protected boolean
processFirstFrameOfLargeMessage(FrameDecoder.IntactFrame frame, ResourceLimits.Limit endpointReserve, ResourceLimits.Limit globalReserve)
protected boolean
processOneContainedMessage(ShareableBytes bytes, ResourceLimits.Limit endpointReserve, ResourceLimits.Limit globalReserve)
Checks limits on bytes in flight and the request rate limiter (if enabled), then takes one of three actions: 1.) If no limits are breached, process the request.protected boolean
processRequest(Envelope request)
protected boolean
processRequest(Envelope request, ClientResourceLimits.Overload backpressure)
-
Methods inherited from class org.apache.cassandra.net.AbstractMessageHandler
acquireCapacity, acquireCapacity, channelInactive, channelRead, handlerAdded, processSubsequentFrameOfLargeMessage, processUpToOneMessage, releaseCapacity, releaseProcessedCapacity
-
Methods inherited from class io.netty.channel.ChannelInboundHandlerAdapter
channelActive, channelReadComplete, channelRegistered, channelUnregistered, channelWritabilityChanged, exceptionCaught, userEventTriggered
-
Methods inherited from class io.netty.channel.ChannelHandlerAdapter
ensureNotSharable, handlerRemoved, isSharable
-
-
-
-
Field Detail
-
LARGE_MESSAGE_THRESHOLD
public static final int LARGE_MESSAGE_THRESHOLD
- See Also:
- Constant Field Values
-
RATE_LIMITER_DELAY_UNIT
public static final java.util.concurrent.TimeUnit RATE_LIMITER_DELAY_UNIT
-
-
Method Detail
-
process
public boolean process(FrameDecoder.Frame frame) throws java.io.IOException
Description copied from interface:FrameDecoder.FrameProcessor
Frame processor that the frames should be handed off to.- Specified by:
process
in interfaceFrameDecoder.FrameProcessor
- Overrides:
process
in classAbstractMessageHandler
- Returns:
- true if more frames can be taken by the processor, false if the decoder should pause until it's explicitly resumed.
- Throws:
java.io.IOException
-
processOneContainedMessage
protected boolean processOneContainedMessage(ShareableBytes bytes, ResourceLimits.Limit endpointReserve, ResourceLimits.Limit globalReserve)
Checks limits on bytes in flight and the request rate limiter (if enabled), then takes one of three actions: 1.) If no limits are breached, process the request. 2.) If a limit is breached, and the connection is configured to throw on overload, throwOverloadedException
. 3.) If a limit is breached, and the connection is not configurd to throw, process the request, and return false to let theFrameDecoder
know it should stop processing frames. If the connection is configured to throwOverloadedException
, requests that breach the rate limit are not counted against that limit.- Specified by:
processOneContainedMessage
in classAbstractMessageHandler
- Returns:
- true if the
FrameDecoder
should continue to process incoming frames, and false if it should stop processing them, effectively applying backpressure to clients - Throws:
ErrorMessage.WrappedException
- with anOverloadedException
if overload occurs and the connection is configured to throw on overload
-
buildOverloadedException
public static OverloadedException buildOverloadedException(ResourceLimits.Limit endpointReserve, ResourceLimits.Limit globalReserve, NonBlockingRateLimiter requestRateLimiter, ClientResourceLimits.Overload overload)
-
buildOverloadedException
public static OverloadedException buildOverloadedException(java.util.function.Supplier<java.lang.String> endpointLimits, NonBlockingRateLimiter requestRateLimiter, ClientResourceLimits.Overload overload)
-
processRequest
protected boolean processRequest(Envelope request)
-
processRequest
protected boolean processRequest(Envelope request, ClientResourceLimits.Overload backpressure)
-
processFirstFrameOfLargeMessage
protected boolean processFirstFrameOfLargeMessage(FrameDecoder.IntactFrame frame, ResourceLimits.Limit endpointReserve, ResourceLimits.Limit globalReserve) throws java.io.IOException
- Specified by:
processFirstFrameOfLargeMessage
in classAbstractMessageHandler
- Throws:
java.io.IOException
-
id
protected java.lang.String id()
- Specified by:
id
in classAbstractMessageHandler
-
processCorruptFrame
protected void processCorruptFrame(FrameDecoder.CorruptFrame frame)
- Specified by:
processCorruptFrame
in classAbstractMessageHandler
-
fatalExceptionCaught
protected void fatalExceptionCaught(java.lang.Throwable cause)
- Specified by:
fatalExceptionCaught
in classAbstractMessageHandler
-
-