You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@activemq.apache.org by John Lilley <jo...@redpointglobal.com.INVALID> on 2023/01/01 14:24:30 UTC

Can I use management API without blocking queue auto-deletion?

Greetings!

In our app, we have a lot of batch “jobs”, each of which stands up an RPC service on a unique queue.  However, when jobs quit, clients may still try to communicate and I don’t want this to hang, I want clients to see an error reply.  To this end, I am implementing a “fallback” service for ended-job RPC queues, of which there can be 100s,  that returns errors.  This is expected to be very low traffic and the polling can be done infrequently (like every few seconds), so performance doesn’t matter.

The queues are set to auto-delete, and in order to keep broker memory down, I don’t want to do anything to prevent auto-deletion.  Because in most cases, nothing will be posted to these queues.  I want to use a strategy like this:

  *   Enumerate queues first, to see which ones exist.
  *   Of the queues that exist, use the queue-based management API to get a message count (see method below).
  *   Only for queues that have a non-zero message count, create a consumer and call receive() to poll for messages.

Will this strategy avoid interfering with the broker’s auto-delete?
Is queue enumeration low-impact enough to call it every few seconds?

Method used for getting queue count (this is all using the artemis-jms-client-all JMS client):

public int getQueueEntryCount(String queueName) {
  return getIntAttribute(queueName, "MessageCount");
}

private int getIntAttribute(final String queueName, final String attributeName) {
  String resourceName = ResourceNames.QUEUE + queueName;
  synchronized (lock) {
    ClientRequestor client = getClient();
    try {
      ClientMessage request = clientSession.createMessage(false);
      ManagementHelper.putAttribute(request, resourceName, attributeName);
      ClientMessage reply = client.request(request);
      if (ManagementHelper.hasOperationSucceeded(reply)) {
        return (int)(long)ManagementHelper.getResult(reply, Long.class);
      } else {
        // Because we cannot tell the difference between queue-does-not-exist and a real error
        return 0;
      }
    }
    catch (Exception e) {
      throw new RuntimeException("Error fetching " + attributeName + " for queue " + queueName, e);
    }
  }
}

Thanks
John



[rg] <https://www.redpointglobal.com/>

John Lilley

Data Management Chief Architect, Redpoint Global Inc.

888 Worcester Street, Suite 200 Wellesley, MA 02482

M: +1 7209385761<tel:+1%207209385761> | john.lilley@redpointglobal.com<ma...@redpointglobal.com>

PLEASE NOTE: This e-mail from Redpoint Global Inc. (“Redpoint”) is confidential and is intended solely for the use of the individual(s) to whom it is addressed. If you believe you received this e-mail in error, please notify the sender immediately, delete the e-mail from your computer and do not copy, print or disclose it to anyone else. If you properly received this e-mail as a customer, partner or vendor of Redpoint, you should maintain its contents in confidence subject to the terms and conditions of your agreement(s) with Redpoint.

Re: Can I use management API without blocking queue auto-deletion?

Posted by Justin Bertram <jb...@apache.org>.
You can save yourself a bit of work by combining your first two steps into
one using the listQueues method on ActiveMQServerControl and passing an
"options" String like:

  {"field":"MESSAGE_COUNT","value":"0","operation":"GREATER_THAN"}

> Will this strategy avoid interfering with the broker’s auto-delete?

Yes.

> Is queue enumeration low-impact enough to call it every few seconds?

It should be, but you should test with a production work-load to ensure
performance meets your expectations.


Another potential solution would be to configure the expiry-address and
expiry-delay for these job addresses so that any message that sits in any
job queue for "too long" would be expired to a common queue and a listener
on that queue could deal with it. This would avoid the polling and likely
simplify your "clean-up" application considerably.


Justin

On Sun, Jan 1, 2023 at 8:25 AM John Lilley
<jo...@redpointglobal.com.invalid> wrote:

> Greetings!
>
>
>
> In our app, we have a lot of batch “jobs”, each of which stands up an RPC
> service on a unique queue.  However, when jobs quit, clients may still try
> to communicate and I don’t want this to hang, I want clients to see an
> error reply.  To this end, I am implementing a “fallback” service for
> ended-job RPC queues, of which there can be 100s,  that returns errors.
> This is expected to be very low traffic and the polling can be done
> infrequently (like every few seconds), so performance doesn’t matter.
>
>
>
> The queues are set to auto-delete, and in order to keep broker memory
> down, I don’t want to do anything to prevent auto-deletion.  Because in
> most cases, nothing will be posted to these queues.  I want to use a
> strategy like this:
>
>    - Enumerate queues first, to see which ones exist.
>    - Of the queues that exist, use the queue-based management API to get
>    a message count (see method below).
>    - Only for queues that have a non-zero message count, create a
>    consumer and call receive() to poll for messages.
>
>
>
> Will this strategy avoid interfering with the broker’s auto-delete?
>
> Is queue enumeration low-impact enough to call it every few seconds?
>
>
>
> Method used for getting queue count (this is all using the artemis-jms-client-all
> JMS client):
>
>
>
> public int getQueueEntryCount(String queueName) {
>
>   return getIntAttribute(queueName, "MessageCount");
>
> }
>
>
>
> private int getIntAttribute(final String queueName, final String
> attributeName) {
>
>   String resourceName = ResourceNames.QUEUE + queueName;
>
>   synchronized (lock) {
>
>     ClientRequestor client = getClient();
>
>     try {
>
>       ClientMessage request = clientSession.createMessage(false);
>
>       ManagementHelper.putAttribute(request, resourceName, attributeName);
>
>       ClientMessage reply = client.request(request);
>
>       if (ManagementHelper.hasOperationSucceeded(reply)) {
>
>         return (int)(long)ManagementHelper.getResult(reply, Long.class);
>
>       } else {
>
>         // Because we cannot tell the difference between
> queue-does-not-exist and a real error
>
>         return 0;
>
>       }
>
>     }
>
>     catch (Exception e) {
>
>       throw new RuntimeException("Error fetching " + attributeName + " for
> queue " + queueName, e);
>
>     }
>
>   }
>
> }
>
>
>
> Thanks
>
> John
>
>
>
> [image: rg] <https://www.redpointglobal.com/>
>
> John Lilley
>
> Data Management Chief Architect, Redpoint Global Inc.
>
> 888 Worcester Street, Suite 200 Wellesley, MA 02482
>
> *M: *+1 7209385761 <+1%207209385761> | john.lilley@redpointglobal.com
>
> PLEASE NOTE: This e-mail from Redpoint Global Inc. (“Redpoint”) is
> confidential and is intended solely for the use of the individual(s) to
> whom it is addressed. If you believe you received this e-mail in error,
> please notify the sender immediately, delete the e-mail from your computer
> and do not copy, print or disclose it to anyone else. If you properly
> received this e-mail as a customer, partner or vendor of Redpoint, you
> should maintain its contents in confidence subject to the terms and
> conditions of your agreement(s) with Redpoint.
>