Hi Everyone, I was a bit slammed leading up to the 0.2 release, and I didn't get a chance to wrap up any of the ack threads, so I thought I'd post a summary of what I actually ended up doing. Please check out the docs for more details, but I'll describe briefly the interface changes in C first and then how I mapped them into python. The following definitions were added to messenger.h, starting with the pn_tracker_t handle:
typedef int64_t pn_tracker_t; There is now a unique handle associated with every call to pn_messenger_put/get. Note that the signatures of pn_messenger_put/get are entirely unchanged. If you care about tracking the status of the delivery associated with a given call you can use the newly added pn_messenger_outgoing_tracker and pn_messenger_incoming_tracker calls to access the handle associated with the last put/get calls respectively: pn_tracker_t pn_messenger_outgoing_tracker(pn_messenger_t *messenger); pn_tracker_t pn_messenger_incoming_tracker(pn_messenger_t *messenger); There is now also an accept mode (defaulting to auto): typedef enum { PN_ACCEPT_MODE_AUTO, PN_ACCEPT_MODE_MANUAL } pn_accept_mode_t; pn_accept_mode_t pn_messenger_get_accept_mode(pn_messenger_t *messenger); int pn_messenger_set_accept_mode(pn_messenger_t *messenger, pn_accept_mode_t mode); If the accept mode is manual, then you have to use the following methods to either accept or reject incoming messages. Note that you can do this either individually or cumulatively, for example to accept all retrieved messages you could do this: pn_messenger_accept(m, pn_messenger_incoming_tracker(m), PN_CUMULATIVE). This is mapped somewhat more conveniently in the python binding. #define PN_CUMULATIVE (0x1) int pn_messenger_accept(pn_messenger_t *messenger, pn_tracker_t tracker, int flags); int pn_messenger_reject(pn_messenger_t *messenger, pn_tracker_t tracker, int flags); Now to access the status of a given delivery, you can simply pass the tracker into the new pn_messenger_status call: pn_status_t pn_messenger_status(pn_messenger_t *messenger, pn_tracker_t tracker); typedef enum { PN_STATUS_UNKNOWN = 0, PN_STATUS_PENDING = 1, PN_STATUS_ACCEPTED = 2, PN_STATUS_REJECTED = 3 } pn_status_t; This call works for both incoming and outgoing deliveries and returns the last known remote status of the delivery associated with the given tracker. Of course by default nothing is actually tracked, so it won't provide much useful information until you turn on tracking. This is done by setting the incoming and outgoing tracking windows via these new calls: int pn_messenger_get_outgoing_window(pn_messenger_t *messenger); int pn_messenger_set_outgoing_window(pn_messenger_t *messenger, int window); int pn_messenger_get_incoming_window(pn_messenger_t *messenger); int pn_messenger_set_incoming_window(pn_messenger_t *messenger, int window); Setting the outgoing tracking window to a positive value will cause the messenger to track the status of that many deliveries *after* calls to send. Setting the incoming tracking window to a positive value will cause the messenger to track the status of that many deliveries *after* calls to accept. You can use pn_messenger_settle to clear either window without waiting for deliveries to roll off the end. This has identical signature to accept/reject except it can work with both incoming and outgoing trackers. int pn_messenger_settle(pn_messenger_t *messenger, pn_tracker_t tracker, int flags); // incoming or outgoing The python bindings for all this simplify it a little bit. The accept_mode, and incoming/outgoing window map to properties of the messenger. Also, unlike in C where we need the return value of put/get to carry the error code, we have exceptions in python, so I simply returned the tracker directly from put/get rather than having a separate accessor for the most recent one. And of course accept/reject take no args and operate cumulatively by default, however you can pass in an individual tracker if you wish to operate non cumulatively. I've attached a diff that illustrates the changes to the send.py/recv.py examples to get them to operate reliably. --Rafael