Hello all,
I had a question about a policy entry memory limit.  I'm creating a broker
with the following attributes:
        <systemUsage>
            <systemUsage sendFailIfNoSpace="true">
                <memoryUsage>
                    <memoryUsage limit="8 MB"/>
                </memoryUsage>
                <storeUsage>
                    <storeUsage limit="32 MB" store="#bridgeStore" />
                </storeUsage>
            </systemUsage>
        </systemUsage>

        <destinationPolicy>
            <policyMap>
                <policyEntries>
                    <policyEntry queue="EVICTIONTESTING" memoryLimit="4 MB"
advisoryWhenFull="true"/>
                </policyEntries>
            </policyMap>
        </destinationPolicy>

(full XML left out for brevity's sake)

This is in a unit test where I'm testing certain boundary cases
(specifically producers with no consumer).  My test is sending persistent
object messages with a payload of 1K, the total message size (according to
AMQ's calculation) is roughly 2.5K.  Since there is no consumer, and i'm
sending a lot of messages, I'm expecting resource allocation exceptions.
What I notice in this situation is that I get ResourceAllocation exceptions
from memory being full.  The exception description is:  "SystemUsage memory
limit reached".  However if I change my memory limit (on the policy entry)
from 4MB to >=6MB (or don't set it altogether) I don't get a resource
allocation exception from the memory limit being reached, but instead I get
it from the store being filled up (which is what my junit test case is
expecting).

Doing more digging, it seems that this occurs when the queue memory limit is
less than 70% of the systemUsage memory limit.  This seems to happen when
o.a.a.broker.region.cursors.StoreQueueCursor#addMessageLast adds a message
to the QueueStorePrefetch, the AbstractPendingMessageCursor's determination
of whether or not there is space available in memory is done via the
systemUsage's memory limit, not the memory limit set on the policy entry for
the particular queue.  So it keeps adding until the highwatermark is
reached, however since it calculating it from the systemusage, but adding it
to the specific queue's memoryUsage it runs out of memory.

Is this expected behavior?  I'm not quite sure I'm using the memory limits
correctly in the first place to assume there is a bug here.

As a side note, when I do get a  ResourceAllocationException from memory
being full I get an advisory message on ActiveMQ.Advisory.FULL.  However
when I get a ResourceAllocationException from the Store being full I don't
get an advisory (BaseDestination#isFull(...) only seems to be called by
o.a.a.broker.region.Queue for one of those cases, again, wasn't sure if I
was expecting something that I shouldn't or if this was an issue.

I'm currently using 5.2.0, I have 5.3.0, however from the digging I've done,
I believe 5.3.0 behaves the same way, however I haven't tested it yet.

Thanks a lot.  If these are issues, I'll certainly be happy to file them
with Jira.

-Brett Humphreys

Reply via email to