[
https://issues.apache.org/jira/browse/AMQ-9813?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18042013#comment-18042013
]
ASF subversion and git services commented on AMQ-9813:
------------------------------------------------------
Commit 25eb613e9a4f05c426884dfeeaadb14f110cef47 in activemq's branch
refs/heads/activemq-5.19.x from Radek Kraus
[ https://gitbox.apache.org/repos/asf?p=activemq.git;h=25eb613e9a ]
AMQ-9813 - fix wrong QueueSize for non-persistent message with TTL
- add "missing" invocation of discardExpiredMessage() method
into tryAddMessageLast(), addMessageFirst(), probably caused
in context of AMQ-5785
- use same "postponed" strategy (outside of synchronization) like was
already done in original commit (see onUsageChanged() method)
(cherry picked from commit 5c5eb335eefc2e0422b17c512eec7796f8ab08df)
> Incorrect QueueSize if Non-Persistent messages with TTL is used
> ---------------------------------------------------------------
>
> Key: AMQ-9813
> URL: https://issues.apache.org/jira/browse/AMQ-9813
> Project: ActiveMQ
> Issue Type: Bug
> Components: Broker
> Affects Versions: 6.2.0, 5.19.1
> Reporter: Radek Kraus
> Assignee: Christopher L. Shannon
> Priority: Major
> Fix For: 6.3.0, 6.1.9, 5.19.2, 6.2.1
>
> Time Spent: 1h 50m
> Remaining Estimate: 0h
>
> Sometimes, I detect a problem with incorrect QueueSize, when non-persitent
> messages with TTL is used.
> *UseCase/Symptoms*
> * produce/consume non-persistent messages with defined TTL (expiration)
> * producerFlowControl=false
> * consumers "are slow", it means that some messages are expired (broker side
> or client side)
> * QueueSize sometimes reports non-zero value even when all messages are
> consumed/expired
> * Broker does not "push" next messages to consumers
> ** JMX method {{browseAsTable()}} does not provide messages
> ** JMX method {{purge()}} does not remove messages (QueueSize is still
> non-zero, nothing is deleted)
> * It seems like messages are expired, but QueueSize still reports non-zero
> values
> * after Broker restart QueueSize is reset to zero (expected for
> non-persitent messages)
> *Analyse*
> * I guess, that problem was introduced by AMQ-5785 (by
> [8b23e07|https://github.com/apache/activemq/commit/8b23e07], where deadlock
> was solved)
> * there is a valid AMQ-5785 comment without next reaction
> * what happens in
> [8b23e07|https://github.com/apache/activemq/commit/8b23e07] commit (nearly
> the same what is written in [AMQ-5785
> comment|https://issues.apache.org/jira/browse/AMQ-5785?focusedCommentId=15607861&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-15607861]):
> ** contract of {{expireOldMessages()}} method was changed to don't invoke
> {{discardExpiredMessage(MessageReference)}} (which is finally responsible to
> "process expired message")
> ** the invocation of {{discardExpiredMessage(MessageReference)}} was moved
> out of synchronized section (deadlock prevention), see
> {{onUsageChanged(Usage, int, int)}} method
> ** but the *problem is that {{expireOldMessages()}} method is invoked from
> next methods* ({{{}tryAddMessageLast(MessageReference, long){}}},
> {{{}addMessageFirst(MessageReference){}}}), where
> *{{discardExpiredMessage(MessageReference)}} method is no longer invoked*
> (after change), *what it is problem from my point of view*
> * IMHO "message expiration process" can be invoked:
> ** from {{onUsageChanged(Usage, int, int)}} method ({{{}UsageListener{}}}),
> asynchronously triggered by Usage.setPercentUsage(int) (thread pool executor)
> ** or "directly" from {{tryAddMessageLast(MessageReference, long)}} (in case
> when {{OrderedPendingList}} is used)
> ** it depends on situations (timings), which method is invoked "at first"
> ** when {{tryAddMessageLast(MessageReference, long)}} method is invoked,
> then expired messages are only removed from {{{}memoryList{}}}, but
> {{discardExpiredMessage(MessageReference)}} is never invoked (what it is the
> problem)
> *PR* (https://github.com/apache/activemq/pull/1551)
> * I added "missing" invocation of
> {{discardExpiredMessage(MessageReference)}} method into
> {{{}tryAddMessageLast(MessageReference, long){}}},
> {{addMessageFirst(MessageReference)}} methods
> * I tried to use same "postponed" strategy (outside of synchronization) like
> was already done in original commit (see {{{}onUsageChanged(Usage, int,
> int){}}}) method
> * I tried to write JUnit test, but it is complicated, because it depends on
> timings (from my expiriences TTL must be very small to simulate the problem,
> see {{{}FullDestinationMemoryMessageExpirationTest{}}})
> Could you please check/analyze my findings?
> In each case (IMHO)
> [8b23e07|https://github.com/apache/activemq/commit/8b23e07] breaks previous
> contract of {{expireOldMessages()}} methods, which can caused that expired
> messages are not "processed", when expiration is triggered by
> {{{}tryAddMessageLast(MessageReference, long){}}},
> {{addMessageFirst(MessageReference)}} methods.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
For further information, visit: https://activemq.apache.org/contact