You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@activemq.apache.org by "Patrick Deasy (Jira)" <ji...@apache.org> on 2024/11/30 01:34:00 UTC

[jira] [Commented] (AMQ-9103) Make HTTP InactivityMonitor timout configurable

    [ https://issues.apache.org/jira/browse/AMQ-9103?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17902001#comment-17902001 ] 

Patrick Deasy commented on AMQ-9103:
------------------------------------

I've been looking into this ticket to expand my knowledge and noticed a few things.

The read check is performed with the [readCheck method of AbstractInactivityMonitor|https://github.com/apache/activemq/blob/main/activemq-client/src/main/java/org/apache/activemq/transport/AbstractInactivityMonitor.java#L248].

 
{code:java}
final void readCheck() {
    int currentCounter = next.getReceiveCounter();
    int previousCounter = lastReceiveCounter.getAndSet(currentCounter);
    if (inReceive.get() || currentCounter != previousCounter) {
        LOG.trace("A receive is in progress, skipping read check.");
        return;
    }
    if (!commandReceived.get() && monitorStarted.get() && !ASYNC_TASKS.isShutdown()) {
        LOG.debug("No message received since last read check for {}. Throwing InactivityIOException.", this);

        try {
            ASYNC_TASKS.execute(new Runnable() {
                @Override
                public void run() {
                    LOG.debug("Running {}", this);
                    onException(new InactivityIOException("Channel was inactive for too (>" + readCheckTime + ") long: " + next.getRemoteAddress()));
                }{code}

The readCheckTime used in the readCheck is configured via the [configuredOk method of InactivityMonitor|https://github.com/apache/activemq/blob/main/activemq-client/src/main/java/org/apache/activemq/transport/InactivityMonitor.java#L106] using the local and remote wireFormatInfo. localWireFormatInfo & remoteWireFormatInfo need to be set for the readCheckTime to be updated.

 

 
{code:java}
long readCheckTime = Math.min(localWireFormatInfo.getMaxInactivityDuration(), remoteWireFormatInfo.getMaxInactivityDuration()); {code}
 

 

The remoteWireFormatInfo can be set with the [onCommand method of AbstractInactivityMonitor|https://github.com/apache/activemq/blob/main/activemq-client/src/main/java/org/apache/activemq/transport/AbstractInactivityMonitor.java#L295].

 
{code:java}
if (command.getClass() == WireFormatInfo.class) {
    synchronized (this) {
        try {
            processInboundWireFormatInfo((WireFormatInfo) command);
        } catch (IOException e) {
            onException(e);
        }
    }
}{code}
 

 

The localWireFormatInfo is only set updated via the [processOutboundWireFormatInfo of InactivityMontior|https://github.com/apache/activemq/blob/main/activemq-client/src/main/java/org/apache/activemq/transport/InactivityMonitor.java#L71].
{code:java}
@Override
protected void processOutboundWireFormatInfo(WireFormatInfo info) throws IOException{
    localWireFormatInfo = info;
    startMonitorThreads();
} {code}
 

 

processOutboundWireFormatInfo is only called from [doOnewaySend of AbstractInactivityMonitor|https://github.com/apache/activemq/blob/main/activemq-client/src/main/java/org/apache/activemq/transport/AbstractInactivityMonitor.java#L333] which is called by [oneway|https://github.com/apache/activemq/blob/main/activemq-client/src/main/java/org/apache/activemq/transport/AbstractInactivityMonitor.java#L310].

 
{code:java}
private void doOnewaySend(Object command) throws IOException {
    if (failed.get()) {
        throw new InactivityIOException("Cannot send, channel has already failed: " + next.getRemoteAddress());
    }
    if (command.getClass() == WireFormatInfo.class) {
        synchronized (this) {
            processOutboundWireFormatInfo((WireFormatInfo) command);
        }
    }
    next.oneway(command);
} {code}
 

The only method I can find which invokes [oneway|https://github.com/apache/activemq/blob/main/activemq-client/src/main/java/org/apache/activemq/transport/AbstractInactivityMonitor.java#L310] with a WireFormatInfo command is the WireFormatNegotiator which invokes [sendWireFormat|https://github.com/apache/activemq/blob/main/activemq-client/src/main/java/org/apache/activemq/transport/WireFormatNegotiator.java#L181] on start.

 
{code:java}
protected void sendWireFormat(WireFormatInfo info) throws IOException {
    next.oneway(info);
} {code}
 

 

The WireFormatNegotiator is only used on the [tcp transport when the OpenWireFormat is used|https://github.com/apache/activemq/blob/main/activemq-client/src/main/java/org/apache/activemq/transport/tcp/TcpTransportFactory.java#L108].

 
{code:java}
// Only need the WireFormatNegotiator if using openwire
if (format instanceof OpenWireFormat) {
    transport = new WireFormatNegotiator(transport, (OpenWireFormat)format, tcpTransport.getMinmumWireFormatVersion());
} {code}
 

 

 

_So to summarize:_

_if the WireFormatNegotiator is only set on a tcp transport with OpenWire,_ 
_and the WireFormatNegotiator is the only class which configures the localWireFormatInfo of the InactivityMonitor_
 _then doesn't that mean that the InactivityMonitor can only have it's read time configured for a tcp transport with OpenWire?_

If this is true does it make sense to come up with a design to support configuration of the InactivityMonitor for other transports and wire formats? Would a wire format negotiator make sense for other transports/wire formats? Or would a simpler means of configuring the InactivityMonitor make sense?

 

Apologies for the huge comment, just trying to relay my thought stream and learn a little more.

 

 

> Make HTTP InactivityMonitor timout configurable
> -----------------------------------------------
>
>                 Key: AMQ-9103
>                 URL: https://issues.apache.org/jira/browse/AMQ-9103
>             Project: ActiveMQ Classic
>          Issue Type: Improvement
>          Components: Transport
>    Affects Versions: 5.17.2
>            Reporter: Chris Lenderman
>            Assignee: Jean-Baptiste Onofré
>            Priority: Major
>             Fix For: 6.2.0
>
>
> Hello!
> Using the HTTP transport, I've noticed a few things
>  * It seems that for large message consumption, the InactivityMonitor will kick in after the 30 second default, even if a message is in the process of being downloaded.
>  * The HTTP InactivityMonitor timeout is not configurable.  I've worked around that temporarily by modifying DEFAULT_CHECK_TIMEOUT_MILLS in [AbstractInactivityMonitor.java|https://github.com/apache/activemq/blob/189a2755a583928af2c71b74e08aa8d52c1d12ef/activemq-client/src/main/java/org/apache/activemq/transport/AbstractInactivityMonitor.java#L49] and updating it to take a Java system property, but it would be idea if it were configurable similar to how it is for the [TCP transport|https://activemq.apache.org/tcp-transport-reference]
> Thanks in advance for your consideration of this feature request!



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@activemq.apache.org
For additional commands, e-mail: issues-help@activemq.apache.org
For further information, visit: https://activemq.apache.org/contact