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.
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.