Search code examples
queueactivemq-classicstomp

When to send ACK or NACK on queue listener in STOMP


The question is when to send the ACK or NACK frames to the broker. The STOMP specification says:

ACK is used to acknowledge consumption of a message from a subscription using client or client-individual acknowledgment. Any messages received from such a subscription will not be considered to have been consumed until the message has been acknowledged via an ACK.

"Consumption" would mean for me "after received and processed". So I can imagine two scenarios.

Scenario A after receiving the message:

function on_message(message)
    message.ack()
    heavy_processing(message)

or Scenario B after the message has been processed:

function on_message(message)
    heavy_processing(message)
    message.ack()

As I understood the NACK is to tell the broker that this listener for example has been temporary marked as inactive. And as I understood as well, the NACK is not to to mark a message as unprocessed because of an exception.

So the following pseudo code would handle ACK, NACK, and exceptions correctly from my understanding:

function on_message(message)
    if online(): # checks resources etc
         message.ack()
    else:
         message.nack()
         return
    try:
        heavy_processing(message) # processing takes 5-10 minutes
    catch Exception: # could be problem with this Listener or malformed message
        message.put_to_dlq() # putting to dlq is a "manual" process
    return

FYI the system I'm talking about is build in Python 3.7.x with Stomp.py module and ActiveMQ.


Solution

  • As you said, 'Consumption' would mean 'after received and processed', you need to acknowledge the message when you have successfully processed your message without any exceptions. So scenario B will be the apt one.

    From the documentation

    NACK is the opposite of ACK. It is used to tell the server that the client did not consume the message.

    So NACK in this context would mean that you have received the message and did not process it successfully.

    Note: If you are maintaining a separate queue for failed messages(ones that cause Exceptions), then you can publish those message to another(dlq queue in your case) and positively acknowledge(ACK) to the original queue for those failed messages.