Thanks for helping!!! I'm new to Artemis, but got really surprised by it's potencial!
I'm working with ActiveMQ Artemis and a Python client built with Qpid Proton (version 0.39.0
). I'm trying to understand how to reject or release a message in Proton Python such that Artemis attempts redelivery, respecting the <max-delivery-attempts>
setting configured in broker.xml
.
Here’s the context:
proton.handlers.MessagingHandler
max-delivery-attempts
), Artemis should move the message to the DLQ.<address-setting match="#">
<max-delivery-attempts>5</max-delivery-attempts>
<redelivery-delay>5000</redelivery-delay>
<dead-letter-address>DLQ</dead-letter-address>
<auto-create-dead-letter-resources>true</auto-create-dead-letter-resources>
<dead-letter-queue-suffix>.DLQ</dead-letter-queue-suffix>
</address-setting>
In on_message
, we release the message when HTTP callback fails:
self.release(event.delivery, delivered=True)
We also tried:
self.settle(event.delivery, state=Delivery.RELEASED)
But neither seemed to make Artemis increment the delivery count. Artemis keeps delivering the same message infinitely and never moves it to the DLQ.
We also tried adding this (suggested in the Artemis docs), but Artemis failed to start:
<persist-delivery-count-before-delivery>true</persist-delivery-count-before-delivery>
What’s the correct way to release or reject a message in Qpid Proton Python so that Artemis:
max-delivery-attempts
?Thanks a lot again!!
RESOLUTION: I wasn't updating the local state object before releasing the message. So in order to use the max-delivery-attempts policy with the DLQ defined in broker.xml, it must complete these local properties:
def on_message(self, event): message = event.message status = send_message_callback(self.enrollment["target_url"], message.body)
if 200 <= status < 300:
self.accept(event.delivery)
else:
# Explicitly NACK the message
local_state = event.delivery.local
local_state.failed = True
local_state.undeliverable = False
local_state.type = event.delivery.MODIFIED
event.delivery.update(local_state)
self.release(event.delivery, delivered=True)
In most cases you want to send a Modified disposition with the delivery failed flag set to true if you want the server to treat the message as a failed attempt and increase the delivery count. If you do this don't set the undeliverable here unless you want the server to avoid sending you the message again on the same connection.