A message transfer. More...
Macros | |
#define | PN_RECEIVED |
The PN_RECEIVED delivery state is a non terminal state indicating how much (if any) message data has been received for a delivery. | |
#define | PN_ACCEPTED |
The PN_ACCEPTED delivery state is a terminal state indicating that the delivery was successfully processed. | |
#define | PN_REJECTED |
The PN_REJECTED delivery state is a terminal state indicating that the delivery could not be processed due to some error condition. | |
#define | PN_RELEASED |
The PN_RELEASED delivery state is a terminal state indicating that the delivery is being returned to the sender. | |
#define | PN_MODIFIED |
The PN_MODIFIED delivery state is a terminal state indicating that the delivery is being returned to the sender and should be annotated by the sender prior to further delivery attempts. | |
Typedefs | |
typedef pn_bytes_t | pn_delivery_tag_t |
An AMQP delivery tag. | |
typedef struct pn_disposition_t | pn_disposition_t |
A delivery state. | |
typedef struct pn_delivery_t | pn_delivery_t |
An AMQP Delivery object. | |
Functions | |
pn_delivery_tag_t | pn_dtag (const char *bytes, size_t size) |
Construct a delivery tag. | |
pn_delivery_t * | pn_delivery (pn_link_t *link, pn_delivery_tag_t tag) |
Create a delivery on a link. | |
void * | pn_delivery_get_context (pn_delivery_t *delivery) |
Get the application context that is associated with a delivery object. | |
void | pn_delivery_set_context (pn_delivery_t *delivery, void *context) |
Set a new application context for a delivery object. | |
pn_record_t * | pn_delivery_attachments (pn_delivery_t *delivery) |
Get the attachments that are associated with a delivery object. | |
pn_delivery_tag_t | pn_delivery_tag (pn_delivery_t *delivery) |
Get the tag for a delivery object. | |
pn_link_t * | pn_delivery_link (pn_delivery_t *delivery) |
Get the parent link for a delivery object. | |
pn_disposition_t * | pn_delivery_local (pn_delivery_t *delivery) |
Get the local disposition for a delivery. | |
uint64_t | pn_delivery_local_state (pn_delivery_t *delivery) |
Get the local disposition state for a delivery. | |
pn_disposition_t * | pn_delivery_remote (pn_delivery_t *delivery) |
Get the remote disposition for a delivery. | |
uint64_t | pn_delivery_remote_state (pn_delivery_t *delivery) |
Get the remote disposition state for a delivery. | |
bool | pn_delivery_settled (pn_delivery_t *delivery) |
Check if a delivery is remotely settled. | |
size_t | pn_delivery_pending (pn_delivery_t *delivery) |
Get the amount of pending message data for a delivery. | |
bool | pn_delivery_partial (pn_delivery_t *delivery) |
Check if a delivery only has partial message data. | |
bool | pn_delivery_aborted (pn_delivery_t *delivery) |
Check if a received delivery has been aborted. | |
bool | pn_delivery_writable (pn_delivery_t *delivery) |
Check if a delivery is writable. | |
bool | pn_delivery_readable (pn_delivery_t *delivery) |
Check if a delivery is readable. | |
bool | pn_delivery_updated (pn_delivery_t *delivery) |
Check if a delivery is updated. | |
void | pn_delivery_update (pn_delivery_t *delivery, uint64_t state) |
Update the disposition of a delivery. | |
void | pn_delivery_clear (pn_delivery_t *delivery) |
Clear the updated flag for a delivery. | |
bool | pn_delivery_current (pn_delivery_t *delivery) |
Return true if delivery is the current delivery for its link. | |
void | pn_delivery_abort (pn_delivery_t *delivery) |
Abort a delivery being sent. | |
void | pn_delivery_settle (pn_delivery_t *delivery) |
Settle a delivery. | |
void | pn_delivery_dump (pn_delivery_t *delivery) |
Utility function for printing details of a delivery. | |
bool | pn_delivery_buffered (pn_delivery_t *delivery) |
Check if a delivery is buffered. | |
pn_delivery_t * | pn_work_head (pn_connection_t *connection) |
Extracts the first delivery on the connection that has pending operations. | |
pn_delivery_t * | pn_work_next (pn_delivery_t *delivery) |
Get the next delivery on the connection that needs has pending operations. | |
uint64_t | pn_disposition_type (pn_disposition_t *disposition) |
Get the type of a disposition. | |
const char * | pn_disposition_type_name (uint64_t disposition_type) |
Name of a disposition type for logging and debugging: "received", "accepted" etc. | |
pn_condition_t * | pn_disposition_condition (pn_disposition_t *disposition) |
Access the condition object associated with a disposition. | |
pn_data_t * | pn_disposition_data (pn_disposition_t *disposition) |
Access the disposition as a raw pn_data_t. | |
uint32_t | pn_disposition_get_section_number (pn_disposition_t *disposition) |
Get the section number associated with a disposition. | |
void | pn_disposition_set_section_number (pn_disposition_t *disposition, uint32_t section_number) |
Set the section number associated with a disposition. | |
uint64_t | pn_disposition_get_section_offset (pn_disposition_t *disposition) |
Get the section offset associated with a disposition. | |
void | pn_disposition_set_section_offset (pn_disposition_t *disposition, uint64_t section_offset) |
Set the section offset associated with a disposition. | |
bool | pn_disposition_is_failed (pn_disposition_t *disposition) |
Check if a disposition has the failed flag set. | |
void | pn_disposition_set_failed (pn_disposition_t *disposition, bool failed) |
Set the failed flag on a disposition. | |
bool | pn_disposition_is_undeliverable (pn_disposition_t *disposition) |
Check if a disposition has the undeliverable flag set. | |
void | pn_disposition_set_undeliverable (pn_disposition_t *disposition, bool undeliverable) |
Set the undeliverable flag on a disposition. | |
pn_data_t * | pn_disposition_annotations (pn_disposition_t *disposition) |
Access the annotations associated with a disposition. | |
A message transfer.
#define PN_ACCEPTED |
#define PN_REJECTED |
The PN_REJECTED delivery state is a terminal state indicating that the delivery could not be processed due to some error condition.
Once in this state there will be no further state changes prior to the delivery being settled.
#define PN_RELEASED |
The PN_RELEASED delivery state is a terminal state indicating that the delivery is being returned to the sender.
Once in this state there will be no further state changes prior to the delivery being settled.
#define PN_MODIFIED |
The PN_MODIFIED delivery state is a terminal state indicating that the delivery is being returned to the sender and should be annotated by the sender prior to further delivery attempts.
Once in this state there will be no further state changes prior to the delivery being settled.
typedef struct pn_disposition_t pn_disposition_t |
A delivery state.
Dispositions record the current state or final outcome of a transfer. Every delivery contains both a local and remote disposition. The local disposition holds the local state of the delivery, and the remote disposition holds the last known remote state of the delivery.
typedef struct pn_delivery_t pn_delivery_t |
An AMQP Delivery object.
A pn_delivery_t object encapsulates all of the endpoint state associated with an AMQP Delivery. Every delivery exists within the context of a pn_link_t object.
The AMQP model for settlement is based on the lifecycle of a delivery at an endpoint. At each end of a link, a delivery is created, it exists for some period of time, and finally it is forgotten, aka settled. Note that because this lifecycle happens independently at both the sender and the receiver, there are actually four events of interest in the combined lifecycle of a given delivery:
Because the sender and receiver are operating concurrently, these events can occur in a variety of different orders, and the order of these events impacts the types of failures that may occur when transferring a delivery. Eliminating scenarios where the receiver creates the delivery first, we have the following possible sequences of interest:
In this configuration the sender settles (i.e. forgets about) the delivery before it even reaches the receiver, and if anything should happen to the delivery in-flight, there is no way to recover, hence the "at most once" semantics.
In this configuration the receiver settles the delivery first, and the sender settles once it sees the receiver has settled. Should anything happen to the delivery in-flight, the sender can resend, however the receiver may have already forgotten the delivery and so it could interpret the resend as a new delivery, hence the "at least once" semantics.
In this configuration the receiver settles only once it has seen that the sender has settled. This provides the sender the option to retransmit, and the receiver has the option to recognize (and discard) duplicates, allowing for exactly once semantics.
Note that in the last scenario the sender needs some way to know when it is safe to settle. This is where delivery state comes in. In addition to these lifecycle related events surrounding deliveries there is also the notion of a delivery state that can change over the lifetime of a delivery, e.g. it might start out as nothing, transition to PN_RECEIVED and then transition to PN_ACCEPTED. In the first two scenarios the delivery state isn't required, however in final scenario the sender would typically trigger settlement based on seeing the delivery state transition to a terminal state like PN_ACCEPTED or PN_REJECTED.
In practice settlement is controlled by application policy, so there may well be more options here, e.g. a sender might not settle strictly based on what has happened at the receiver, it might also choose to impose some time limit and settle after that period has expired, or it could simply have a sliding window of the last N deliveries and settle the oldest whenever a new one comes along.
pn_delivery_tag_t pn_dtag | ( | const char * | bytes, |
size_t | size | ||
) |
pn_delivery_t * pn_delivery | ( | pn_link_t * | link, |
pn_delivery_tag_t | tag | ||
) |
Create a delivery on a link.
Every delivery object within a link must be supplied with a unique tag. Links maintain a sequence of delivery object in the order that they are created.
[in] | link | a link object |
[in] | tag | the delivery tag |
void * pn_delivery_get_context | ( | pn_delivery_t * | delivery | ) |
Get the application context that is associated with a delivery object.
The application context for a delivery may be set using pn_delivery_set_context.
[in] | delivery | the delivery whose context is to be returned. |
void pn_delivery_set_context | ( | pn_delivery_t * | delivery, |
void * | context | ||
) |
Set a new application context for a delivery object.
The application context for a delivery object may be retrieved using pn_delivery_get_context.
[in] | delivery | the delivery object |
[in] | context | the application context |
pn_record_t * pn_delivery_attachments | ( | pn_delivery_t * | delivery | ) |
Get the attachments that are associated with a delivery object.
[in] | delivery | the delivery whose attachments are to be returned. |
pn_delivery_tag_t pn_delivery_tag | ( | pn_delivery_t * | delivery | ) |
Get the tag for a delivery object.
[in] | delivery | a delivery object |
pn_link_t * pn_delivery_link | ( | pn_delivery_t * | delivery | ) |
pn_disposition_t * pn_delivery_local | ( | pn_delivery_t * | delivery | ) |
Get the local disposition for a delivery.
The pointer returned by this object is valid until the delivery is settled.
[in] | delivery | a delivery object |
uint64_t pn_delivery_local_state | ( | pn_delivery_t * | delivery | ) |
Get the local disposition state for a delivery.
[in] | delivery | a delivery object |
pn_disposition_t * pn_delivery_remote | ( | pn_delivery_t * | delivery | ) |
Get the remote disposition for a delivery.
The pointer returned by this object is valid until the delivery is settled.
[in] | delivery | a delivery object |
uint64_t pn_delivery_remote_state | ( | pn_delivery_t * | delivery | ) |
bool pn_delivery_settled | ( | pn_delivery_t * | delivery | ) |
Check if a delivery is remotely settled.
[in] | delivery | a delivery object |
size_t pn_delivery_pending | ( | pn_delivery_t * | delivery | ) |
bool pn_delivery_partial | ( | pn_delivery_t * | delivery | ) |
Check if a delivery only has partial message data.
The receiver can expect more PN_DELIVERY events for this delivery containing the remainder of this message.
[in] | delivery | a delivery object |
bool pn_delivery_aborted | ( | pn_delivery_t * | delivery | ) |
Check if a received delivery has been aborted.
An aborted delivery means the sender cannot complete this message and the receiver should discard any data already received. The link remains open for future messages.
You must still call pn_delivery_settle() to free local resources. An aborted delivery consumes a credit, use pn_link_flow() to issue new credit as for a successful delivery.
Calling pn_link_recv() when the current delivery is aborted returns PN_ABORTED.
[in] | delivery | a delivery object |
bool pn_delivery_writable | ( | pn_delivery_t * | delivery | ) |
Check if a delivery is writable.
A delivery is considered writable if it is the current delivery on an outgoing link, and the link has positive credit.
[in] | delivery | a delivery object |
bool pn_delivery_readable | ( | pn_delivery_t * | delivery | ) |
bool pn_delivery_updated | ( | pn_delivery_t * | delivery | ) |
Check if a delivery is updated.
A delivery is considered updated whenever the peer communicates a new disposition for the delivery. Once a delivery becomes updated, it will remain so until pn_delivery_clear is called.
[in] | delivery | a delivery object |
void pn_delivery_update | ( | pn_delivery_t * | delivery, |
uint64_t | state | ||
) |
void pn_delivery_clear | ( | pn_delivery_t * | delivery | ) |
Clear the updated flag for a delivery.
See pn_delivery_updated.
[in] | delivery | a delivery object |
bool pn_delivery_current | ( | pn_delivery_t * | delivery | ) |
Return true if delivery is the current delivery for its link.
[in] | delivery | a delivery object |
void pn_delivery_abort | ( | pn_delivery_t * | delivery | ) |
Abort a delivery being sent.
Aborting means the sender cannot complete this message. It will not send any more data, and data sent so far should be discarded by the receiver. The link remains open for future messages.
If some data has already been sent on the network, an AMQP "aborted" frame will be sent to inform the peer. If no data has yet been sent, the delivery will simply be forgotten.
The delivery will be freed, and cannot be used after the call.
[in] | delivery | a delivery object |
void pn_delivery_settle | ( | pn_delivery_t * | delivery | ) |
void pn_delivery_dump | ( | pn_delivery_t * | delivery | ) |
Utility function for printing details of a delivery.
[in] | delivery | a delivery object |
bool pn_delivery_buffered | ( | pn_delivery_t * | delivery | ) |
Check if a delivery is buffered.
A delivery that is buffered has not yet been written to the wire.
Note that returning false does not imply that a delivery was definitely written to the wire. If false is returned, it is not known whether the delivery was actually written to the wire or not.
[in] | delivery | a delivery object |
pn_delivery_t * pn_work_head | ( | pn_connection_t * | connection | ) |
Extracts the first delivery on the connection that has pending operations.
Retrieves the first delivery on the Connection that has pending operations. A readable delivery indicates message data is waiting to be read. A writable delivery indicates that message data may be sent. An updated delivery indicates that the delivery's disposition has changed. A delivery will never be both readable and writable, but it may be both readable and updated or both writable and updated.
[in] | connection | the connection |
pn_delivery_t * pn_work_next | ( | pn_delivery_t * | delivery | ) |
Get the next delivery on the connection that needs has pending operations.
[in] | delivery | the previous delivery retrieved from either pn_work_head or pn_work_next |
uint64_t pn_disposition_type | ( | pn_disposition_t * | disposition | ) |
Get the type of a disposition.
Defined values are:
[in] | disposition | a disposition object |
pn_condition_t * pn_disposition_condition | ( | pn_disposition_t * | disposition | ) |
Access the condition object associated with a disposition.
The pn_condition_t object retrieved by this operation may be modified prior to updating a delivery. When a delivery is updated, the condition described by the disposition is reported to the peer if applicable to the current delivery state, e.g. states such as PN_REJECTED.
The pointer returned by this operation is valid until the parent delivery is settled.
[in] | disposition | a disposition object |
pn_data_t * pn_disposition_data | ( | pn_disposition_t * | disposition | ) |
Access the disposition as a raw pn_data_t.
Dispositions are an extension point in the AMQP protocol. The disposition interface provides setters/getters for those dispositions that are predefined by the specification, however access to the raw disposition data is provided so that other dispositions can be used.
The pn_data_t pointer returned by this operation is valid until the parent delivery is settled.
[in] | disposition | a disposition object |
uint32_t pn_disposition_get_section_number | ( | pn_disposition_t * | disposition | ) |
Get the section number associated with a disposition.
[in] | disposition | a disposition object |
void pn_disposition_set_section_number | ( | pn_disposition_t * | disposition, |
uint32_t | section_number | ||
) |
Set the section number associated with a disposition.
[in] | disposition | a disposition object |
[in] | section_number | a section number |
uint64_t pn_disposition_get_section_offset | ( | pn_disposition_t * | disposition | ) |
Get the section offset associated with a disposition.
[in] | disposition | a disposition object |
void pn_disposition_set_section_offset | ( | pn_disposition_t * | disposition, |
uint64_t | section_offset | ||
) |
Set the section offset associated with a disposition.
[in] | disposition | a disposition object |
[in] | section_offset | a section offset |
bool pn_disposition_is_failed | ( | pn_disposition_t * | disposition | ) |
Check if a disposition has the failed flag set.
[in] | disposition | a disposition object |
void pn_disposition_set_failed | ( | pn_disposition_t * | disposition, |
bool | failed | ||
) |
Set the failed flag on a disposition.
[in] | disposition | a disposition object |
[in] | failed | the value of the failed flag |
bool pn_disposition_is_undeliverable | ( | pn_disposition_t * | disposition | ) |
Check if a disposition has the undeliverable flag set.
[in] | disposition | a disposition object |
void pn_disposition_set_undeliverable | ( | pn_disposition_t * | disposition, |
bool | undeliverable | ||
) |
Set the undeliverable flag on a disposition.
[in] | disposition | a disposition object |
[in] | undeliverable | the value of the undeliverable flag |
pn_data_t * pn_disposition_annotations | ( | pn_disposition_t * | disposition | ) |
Access the annotations associated with a disposition.
The pn_data_t object retrieved by this operation may be modified prior to updating a delivery. When a delivery is updated, the annotations described by the pn_data_t are reported to the peer if applicable to the current delivery state, e.g. states such as PN_MODIFIED. The pn_data_t must be empty or contain a symbol keyed map.
The pointer returned by this operation is valid until the parent delivery is settled.
[in] | disposition | a disposition object |