API Overview¶
An overview of the model¶
Messages are transferred between connected peers over ‘links’. At the sending peer the link is called a sender. At the receiving peer it is called a receiver. Messages are sent by senders and received by receivers. Links may have named ‘source’ and ‘target’ addresses (for example to identify the queue from which message were to be received or to which they were to be sent).
Links are established over sessions. Sessions are established over connections. Connections are (generally) established between two uniquely identified containers. Though a connection can have multiple sessions, often this is not needed. The container API allows you to ignore sessions unless you actually require them.
The sending of a message over a link is called a delivery. The message is the content sent, including all meta-data such as headers and annotations. The delivery is the protocol exchange associated with the transfer of that content.
To indicate that a delivery is complete, either the sender or the receiver ‘settles’ it. When the other side learns that it has been settled, they will no longer communicate about that delivery. The receiver can also indicate whether they accept or reject the message.
Three different delivery levels or ‘guarantees’ can be achieved: at-most-once, at-least-once or exactly-once. See Delivery guarantees for more detail.
A summary of the most commonly used classes and members¶
A brief summary of some of the key classes follows.
The Container
class is a convenient entry
point into the API, allowing connections and links to be
established. Applications are structured as one or more event
handlers. Handlers can be set at Container, Connection, or Link
scope. Messages are sent by establishing an appropriate sender and
invoking its send()
method. This is
typically done when the sender is sendable, a condition indicated by
the on_sendable()
event, to
avoid excessive build up of messages. Messages can be received by
establishing an appropriate receiver and handling the
on_message()
event.
- class proton.reactor.Container(*handlers, **kwargs)[source]
Bases:
Reactor
A representation of the AMQP concept of a ‘container’, which loosely speaking is something that establishes links to or from another container, over which messages are transfered. This is an extension to the Reactor class that adds convenience methods for creating connections and sender- or receiver- links.
- container_id¶
The identifier used to identify this container in any connections it establishes. Container names should be unique. By default a UUID will be used.
The
connect()
method returns an instance ofConnection
, thecreate_receiver()
method returns an instance ofReceiver
and thecreate_sender()
method returns an instance ofSender
.- connect(url: str | Url | None = None, urls: List[str] | None = None, address: str | None = None, handler: Handler | None = None, reconnect: None | Literal[False] | Backoff = None, heartbeat: float | None = None, ssl_domain: SSLDomain | None = None, **kwargs) Connection [source]
Initiates the establishment of an AMQP connection.
An optional JSON configuration file may be used to specify some connection parameters. If present, these will override some of those given in this call (see note below). Some connection parameters (for SSL/TLS) can only be provided through this file. The configuration file is located by searching for it as follows:
The location set in the environment variable
MESSAGING_CONNECT_FILE
./connect.json
~/.config/messaging/connect.json
/etc/messaging/connect.json
To use SSL/TLS for encryption (when an
amqps
URL scheme is used), the above configuration file must contain atls
submap containing the following configuration entries (Seeproton.SSLDomain
for details):ca
: Path to a database of trusted CAs that the server will advertise.cert
: Path to a file/database containing the identifying certificate.key
: An optional key to access the identifying certificate.verify
: IfFalse
, do not verify the peer name (proton.SSLDomain.ANONYMOUS_PEER
) or certificate. By default (or ifTrue
) verify the peer name and certificate using theca
above (proton.SSLDomain.VERIFY_PEER_NAME
).
- Parameters:
url – URL string of process to connect to
urls – list of URL strings of process to try to connect to
reconnect – Reconnect is enabled by default. You can pass in an instance of
Backoff
to control reconnect behavior. A value ofFalse
will prevent the library from automatically trying to reconnect if the underlying socket is disconnected before the connection has been closed.heartbeat – A value in seconds indicating the desired frequency of heartbeats used to test the underlying socket is alive.
ssl_domain – SSL configuration.
handler – a connection scoped handler that will be called to process any events in the scope of this connection or its child links.
kwargs –
sasl_enabled
(bool
), which determines whether a sasl layer is used for the connection.allowed_mechs
(str
), an optional string specifying the SASL mechanisms allowed for this connection; the value is a space-separated list of mechanism names; the mechanisms allowed by default are determined by your SASL library and system configuration, with two exceptions:GSSAPI
andGSS-SPNEGO
are disabled by default; to enable them, you must explicitly add them using this option; clients must set the allowed mechanisms before the outgoing connection is attempted; servers must set them before the listening connection is setup.allow_insecure_mechs
(bool
), a flag indicating whether insecure mechanisms, such as PLAIN over a non-encrypted socket, are allowed.password
(str
), the authentication secret. Ignored withoutuser
kwarg also being present.user
(str
), the user to authenticate.virtual_host
(str
), the hostname to set in the Open performative used by peer to determine the correct back-end service for the client; ifvirtual_host
is not supplied the host field from the URL is used instead.offered_capabilities
, a list of capabilities being offered to the peer. The list must contain symbols (or strings, which will be converted to symbols).desired_capabilities
, a list of capabilities desired from the peer. The list must contain symbols (or strings, which will be converted to symbols).properties
, a list of connection properties. This must be a map with symbol keys (or string keys, which will be converted to symbol keys).sni
(str
), a hostname to use with SSL/TLS Server Name Indication (SNI)max_frame_size
(int
), the maximum allowable TCP packet size between the peers.
- Returns:
A new connection object.
Note
Only one of
url
orurls
should be specified.Note
The following kwargs will be overridden by the values found in the JSON configuration file (if they exist there):
password
user
and the following kwargs will be overridden by the values found in the
sasl
sub-map of the above configuration file (if they exist there):sasl_enabled
allowed_mechs
- create_receiver(context: Connection | Url | str, source: str | None = None, target: str | None = None, name: str | None = None, dynamic: bool = False, handler: Handler | None = None, options: ReceiverOption | List[ReceiverOption] | LinkOption | List[LinkOption] | None = None) Receiver [source]
Initiates the establishment of a link over which messages can be received (aka a subscription).
There are two patterns of use:
(1) A connection can be passed as the first argument, in which case the link is established on that connection. In this case the source address can be specified as the second argument (or as a keyword argument). The target address can also be specified if desired.
(2) Alternatively a URL can be passed as the first argument. In this case a new connection will be established on which the link will be attached. If a path is specified and the source is not, then the path of the URL is used as the target address.
The name of the link may be specified if desired, otherwise a unique name will be generated.
Various
LinkOption
s can be specified to further control the attachment.- Parameters:
context – A connection object or a URL.
source – Address of source node.
target – Address of target node.
name – Receiver name.
dynamic – If
True
, indicates dynamic creation of the receiver.handler – Event handler for this receiver.
options – A single option, or a list of receiver options
- Returns:
New receiver instance.
- create_sender(context: str | Url | Connection, target: str | None = None, source: str | None = None, name: str | None = None, handler: Handler | None = None, tags: Callable[[], bytes] | None = None, options: SenderOption | List[SenderOption] | LinkOption | List[LinkOption] | None = None) Sender [source]
Initiates the establishment of a link over which messages can be sent.
There are two patterns of use:
A connection can be passed as the first argument, in which case the link is established on that connection. In this case the target address can be specified as the second argument (or as a keyword argument). The source address can also be specified if desired.
Alternatively a URL can be passed as the first argument. In this case a new connection will be established on which the link will be attached. If a path is specified and the target is not, then the path of the URL is used as the target address.
The name of the link may be specified if desired, otherwise a unique name will be generated.
Various
LinkOption
s can be specified to further control the attachment.- Parameters:
context – A connection object or a URL.
target – Address of target node.
source – Address of source node.
name – Sender name.
handler – Event handler for this sender.
tags – Function to generate tags for this sender of the form
def simple_tags():
and returns abytes
typeoptions – A single option, or a list of sender options
- Returns:
New sender instance.
- run() None
Start the processing of events and messages for this container.
- schedule(delay: float | int, handler: Handler) Task
Schedule a task to run on this container after a given delay, and using the supplied handler.
- Parameters:
delay –
handler –
- class proton.Connection(impl: Any = None)[source]
A representation of an AMQP connection.
- close() None [source]
Closes the connection.
In more detail, this moves the local state of the connection to the
CLOSED
state and triggers a close frame to be sent to the peer. A connection is fully closed once both peers have closed it.
- property container: str
The container name for this connection object.
- property hostname: str | None
Set the name of the host (either fully qualified or relative) to which this connection is connecting to. This information may be used by the remote peer to determine the correct back-end service to connect the client to. This value will be sent in the Open performative, and will be used by SSL and SASL layers to identify the peer.
- open() None [source]
Opens the connection.
In more detail, this moves the local state of the connection to the
ACTIVE
state and triggers an open frame to be sent to the peer. A connection is fully active once both peers have opened it.
- property remote_container: str | None
The container identifier specified by the remote peer for this connection.
This will return
None
until the :const:’REMOTE_ACTIVE` state is reached. SeeEndpoint
for more details on endpoint state.Any (non
None
) name returned by this operation will be valid until the connection object is unbound from a transport or freed, whichever happens sooner.
- property remote_desired_capabilities
The capabilities desired by the remote peer for this connection.
This operation will return a
Data
object that is valid until the connection object is freed. ThisData
object will be empty until the remote connection is opened as indicated by theREMOTE_ACTIVE
flag.- Type:
- property remote_hostname: str | None
The hostname specified by the remote peer for this connection.
This will return
None
until theREMOTE_ACTIVE
state is reached. SeeEndpoint
for more details on endpoint state.Any (non
None
) name returned by this operation will be valid until the connection object is unbound from a transport or freed, whichever happens sooner.
- property remote_offered_capabilities
The capabilities offered by the remote peer for this connection.
This operation will return a
Data
object that is valid until the connection object is freed. ThisData
object will be empty until the remote connection is opened as indicated by theREMOTE_ACTIVE
flag.- Type:
- property remote_properties
The properties specified by the remote peer for this connection.
This operation will return a
Data
object that is valid until the connection object is freed. ThisData
object will be empty until the remote connection is opened as indicated by theREMOTE_ACTIVE
flag.- Type:
- property state: int
The state of the connection as a bit field. The state has a local and a remote component. Each of these can be in one of three states:
UNINIT
,ACTIVE
orCLOSED
. These can be tested by masking againstLOCAL_UNINIT
,LOCAL_ACTIVE
,LOCAL_CLOSED
,REMOTE_UNINIT
,REMOTE_ACTIVE
andREMOTE_CLOSED
.
- class proton.Receiver(impl)[source]
Bases:
Link
A link over which messages are received.
- drain(n: int) None [source]
Grant credit for incoming deliveries on this receiver, and set drain mode to true.
Use
drain_mode
to set the drain mode explicitly.- Parameters:
n – The amount by which to increment the link credit
- draining() bool [source]
Check if a link is currently draining. A link is defined to be draining when drain mode is set to
True
, and the sender still has excess credit.- Returns:
True
if the link is currently draining,False
otherwise.
- flow(n: int) None [source]
Increases the credit issued to the remote sender by the specified number of messages.
- Parameters:
n – The credit to be issued to the remote sender.
- recv(limit: int) bytes | None [source]
Receive message data for the current delivery on this receiver.
Note
The link API can be used to stream large messages across the network, so just because there is no data to read does not imply the message is complete. To ensure the entirety of the message data has been read, either invoke
recv()
untilNone
is returned.- Parameters:
limit – the max data size to receive of this message
- Returns:
The received message data, or
None
if the message has been completely received.- Raise:
Timeout
if timed outInterrupt
if interruptedLinkException
for all other exceptions
- class proton.Sender(impl)[source]
Bases:
Link
A link over which messages are sent.
- offered(n: int) None [source]
Signal the availability of deliveries for this Sender.
- Parameters:
n – Credit the number of deliveries potentially available for transfer.
- send(obj: bytes | Message, tag: str | None = None) int | Delivery [source]
A convenience method to send objects as message content.
Send specified object over this sender; the object is expected to have a
send()
method on it that takes the sender and an optional tag as arguments.Where the object is a
Message
, this will send the message over this link, creating a new delivery for the purpose.
- class proton.Link(impl)[source]
A representation of an AMQP link (a unidirectional channel for transferring messages), of which there are two concrete implementations,
Sender
andReceiver
.The
source()
,target()
,remote_source()
andremote_target()
methods all return an instance ofTerminus
.- property connection: Connection
The connection on which this link was attached.
- property credit: int
The amount of outstanding credit on this link.
Links use a credit based flow control scheme. Every receiver maintains a credit balance that corresponds to the number of deliveries that the receiver can accept at any given moment. As more capacity becomes available at the receiver (see
Receiver.flow()
), it adds credit to this balance and communicates the new balance to the sender. Whenever a delivery is sent/received, the credit balance maintained by the link is decremented by one. Once the credit balance at the sender reaches zero, the sender must pause sending until more credit is obtained from the receiver.
- property is_receiver: bool
True
if this link is a receiver,False
otherwise.
- property is_sender: bool
True
if this link is a sender,False
otherwise.
- property name: str
The name of the link.
- property queued: int
The number of queued deliveries for a link.
Links may queue deliveries for a number of reasons, for example there may be insufficient credit to send them to the receiver (see
credit()
), or they simply may not have yet had a chance to be written to the wire. This operation will return the number of queued deliveries on a link.
- property remote_source: Terminus
The source of the link as described by the remote peer. The returned object is valid until the link is freed. The remote
Terminus
object will be empty until the link is remotely opened as indicated by theREMOTE_ACTIVE
flag.
- property remote_target: Terminus
The target of the link as described by the remote peer. The returned object is valid until the link is freed. The remote
Terminus
object will be empty until the link is remotely opened as indicated by theREMOTE_ACTIVE
flag.
- property session: Session
The parent session for this link.
- property source: Terminus
The source of the link as described by the local peer. The returned object is valid until the link is freed.
- property state: int
The state of the link as a bit field. The state has a local and a remote component. Each of these can be in one of three states:
UNINIT
,ACTIVE
orCLOSED
. These can be tested by masking againstLOCAL_UNINIT
,LOCAL_ACTIVE
,LOCAL_CLOSED
,REMOTE_UNINIT
,REMOTE_ACTIVE
andREMOTE_CLOSED
.
- property target: Terminus
The target of the link as described by the local peer. The returned object is valid until the link is freed.
- class proton.Delivery(impl)[source]
Tracks and/or records the delivery of a message over a link.
- property connection: Connection
The
Connection
over which the delivery was sent or received.
- property local_state: int | DispositionType
A local state of the delivery.
- property partial: bool
True
for an incoming delivery if not all the data is yet available,False
otherwise.
- property readable: bool
True
for an incoming delivery that has data to read,False
otherwise..
- property remote_state: int | DispositionType
A remote state of the delivery as indicated by the remote peer.
- settle() None [source]
Settles the delivery locally. This indicates the application considers the delivery complete and does not wish to receive any further events about it. Every delivery should be settled locally.
- property settled: bool
True
if the delivery has been settled by the remote peer,False
otherwise.
- update(state: int | DispositionType) None [source]
Set the local state of the delivery e.g.
ACCEPTED
,REJECTED
,RELEASED
.- Parameters:
state – State of delivery
- property writable: bool
True
for an outgoing delivery to which data can now be written,False
otherwise..
- class proton.handlers.MessagingHandler(prefetch: int = 10, auto_accept: bool = True, auto_settle: bool = True, peer_close_is_error: bool = False)[source]
A general purpose handler that makes the proton-c events somewhat simpler to deal with and/or avoids repetitive tasks for common use cases.
- Parameters:
prefetch – Initial flow credit for receiving messages, defaults to 10.
auto_accept – If
True
, accept all messages (default). Otherwise messages must be individually accepted or rejected.auto_settle – If
True
(default), automatically settle messages upon receiving a settled disposition for that delivery. Otherwise messages must be explicitly settled.peer_close_is_error – If
True
, a peer endpoint closing will be treated as an error with an error callback. Otherwise (default), the normal callbacks for the closing will occur.
- accept(delivery: Delivery) None
Accepts a received message.
Note
This method cannot currently be used in combination with transactions. See
proton.reactor.Transaction
for transactional methods.- Parameters:
delivery – The message delivery tracking object
- on_accepted(event: Event) None [source]
Called when the remote peer accepts an outgoing message.
- Parameters:
event – The underlying event object. Use this to obtain further information on the event.
- on_connection_error(event: Event) None [source]
Called when the peer closes the connection with an error condition.
- Parameters:
event (
proton.Event
) – The underlying event object. Use this to obtain further information on the event.
- on_disconnected(event: Event) None [source]
Called when the socket is disconnected.
- Parameters:
event – The underlying event object. Use this to obtain further information on the event.
- on_link_error(event: Event) None [source]
Called when the peer closes the link with an error condition.
- Parameters:
event – The underlying event object. Use this to obtain further information on the event.
- on_message(event: Event) None [source]
Called when a message is received. The message itself can be obtained as a property on the event. For the purpose of referring to this message in further actions (e.g. if explicitly accepting it, the
delivery
should be used, also obtainable via a property on the event.- Parameters:
event – The underlying event object. Use this to obtain further information on the event. In particular, the message itself may be obtained by accessing
event.message
.
- on_reactor_init(event: Event) None [source]
Called when the event loop - the reactor - starts.
- Parameters:
event – The underlying event object. Use this to obtain further information on the event.
- on_rejected(event: Event) None [source]
Called when the remote peer rejects an outgoing message.
- Parameters:
event – The underlying event object. Use this to obtain further information on the event.
- on_sendable(event: Event) None [source]
Called when the sender link has credit and messages can therefore be transferred.
- Parameters:
event – The underlying event object. Use this to obtain further information on the event.
- on_session_error(event: Event) None [source]
Called when the peer closes the session with an error condition.
- Parameters:
event – The underlying event object. Use this to obtain further information on the event.
- on_settled(event: Event) None [source]
Called when the remote peer has settled the outgoing message. This is the point at which it should never be retransmitted.
- Parameters:
event – The underlying event object. Use this to obtain further information on the event.
- on_start(event: Event) None [source]
Called when the event loop starts. (Just an alias for on_reactor_init)
- Parameters:
event – The underlying event object. Use this to obtain further information on the event.
- reject(delivery: Delivery) None
Rejects a received message that is considered invalid or unprocessable.
Note
This method cannot currently be used in combination with transactions. See
proton.reactor.Transaction
for transactional methods.- Parameters:
delivery – The message delivery tracking object
- release(delivery: Delivery, delivered: bool = True) None
Releases a received message, making it available at the source for any (other) interested receiver. The
delivered
parameter indicates whether this should be considered a delivery attempt (and the delivery count updated) or not.Note
This method cannot currently be used in combination with transactions. See
proton.reactor.Transaction
for transactional methods.- Parameters:
delivery – The message delivery tracking object
delivered – If
True
, the message will be annotated with a delivery attempt (setting delivery flagproton.Delivery.MODIFIED
). Otherwise, the message will be returned without the annotation and released (setting delivery flagproton.Delivery.RELEASED
- settle(delivery: Delivery, state: DispositionType | None = None) None
Settles the message delivery, and optionally updating the delivery state.
- Parameters:
delivery – The message delivery tracking object
state – The delivery state, or
None
if no update is to be performed.
- class proton.Event(impl, number, clsname, context)[source]
Notification of a state change in the protocol engine.
- property connection: Connection | None
The connection associated with the event, or
None
if none is associated with it.
- property context: Any | None | Connection | Session | Link | Delivery | Transport
The context object associated with the event.
- Type:
Depends on the type of event, and include the following: -
Connection
-Session
-Link
-Delivery
-Transport
- property delivery: Delivery | None
The delivery associated with the event, or
None
if none is associated with it.
- property link: Sender | Receiver | None
The link associated with the event, or
None
if none is associated with it.
- property reactor: Container
Deprecated - The
reactor.Container
(was reactor) associated with the event.
- property receiver: Receiver | None
The receiver link associated with the event, or
None
if none is associated with it. This is essentially an alias forlink
property, that does an additional check on the type of the link.
- property sender: Sender | None
The sender link associated with the event, or
None
if none is associated with it. This is essentially an alias forlink
property, that does an additional check on the type of the link.
- property session: Session | None
The session associated with the event, or
None
if none is associated with it.
- class proton.Message(body: bytes | str | dict | list | int | float | UUID | Described | None = None, **kwargs)[source]
The
Message
class is a mutable holder of message content.- Variables:
instructions (
dict
) – delivery instructions for the message (“Delivery Annotations” in the AMQP 1.0 spec)~.annotations (
dict
) – infrastructure defined message annotations (“Message Annotations” in the AMQP 1.0 spec)~.properties (
dict
) – application defined message propertiesbody – message body
- Parameters:
kwargs – Message property name/value pairs to initialize the Message
- property address: str | None
The address of the message.
- Raise:
MessageException
if there is any Proton error when using the setter.
- property content_encoding: symbol
The content-encoding of the message.
- Raise:
MessageException
if there is any Proton error when using the setter.
- property content_type: symbol
The RFC-2046 [RFC2046] MIME type for the message body.
- Raise:
MessageException
if there is any Proton error when using the setter.
- property correlation_id: str | bytes | UUID | ulong | None
The correlation-id for the message.
- Type:
The valid AMQP types for a correlation-id are one of:
int
(unsigned)uuid.UUID
bytes
str
- property creation_time: float
The creation time of the message in seconds using the Unix time_t [IEEE1003] encoding.
- Raise:
MessageException
if there is any Proton error when using the setter.
- decode(data: bytes) None [source]
- property delivery_count: int
The number of delivery attempts made for this message.
- Raise:
MessageException
if there is any Proton error when using the setter.
- property durable: bool
The durable property indicates that the message should be held durably by any intermediaries taking responsibility for the message.
- Raise:
MessageException
if there is any Proton error when using the setter.
- encode() bytes [source]
- property expiry_time: float
The absolute expiry time of the message in seconds using the Unix time_t [IEEE1003] encoding.
- Raise:
MessageException
if there is any Proton error when using the setter.
- property first_acquirer: bool
True
iff the recipient is the first to acquire the message,False
otherwise.- Raise:
MessageException
if there is any Proton error when using the setter.
- property group_id: str | None
The group id of the message.
- Raise:
MessageException
if there is any Proton error when using the setter.
- property group_sequence: int
The sequence of the message within its group.
- Raise:
MessageException
if there is any Proton error when using the setter.
- property id: str | bytes | UUID | ulong | None
The globally unique id of the message, and can be used to determine if a received message is a duplicate. The allowed types to set the id are:
- Type:
The valid AMQP types for an id are one of:
int
(unsigned)uuid.UUID
bytes
str
- property priority: int
The relative priority of the message, with higher numbers indicating higher priority. The number of available priorities depends on the implementation, but AMQP defines the default priority as the value
4
. See the OASIS AMQP 1.0 standard for more details on message priority.- Raise:
MessageException
if there is any Proton error when using the setter.
- recv(link: Sender) None [source]
Receives and decodes the message content for the current
Delivery
from the link. Upon success it will return the current delivery for the link. If there is no current delivery, or if the current delivery is incomplete, or if the link is not a receiver, it will returnNone
.- Parameters:
link – The link to receive a message from
- Returns:
the delivery associated with the decoded message (or None)
- property reply_to: str | None
The reply-to address for the message.
- Raise:
MessageException
if there is any Proton error when using the setter.
- property reply_to_group_id: str | None
The group-id for any replies.
- Raise:
MessageException
if there is any Proton error when using the setter.
- send(sender: Sender, tag: str | None = None) Delivery [source]
Encodes and sends the message content using the specified sender, and, if present, using the specified tag. Upon success, will return the
Delivery
object for the sent message.- Parameters:
sender – The sender to send the message
tag – The delivery tag for the sent message
- Returns:
The delivery associated with the sent message
- property subject: str | None
The subject of the message.
- Raise:
MessageException
if there is any Proton error when using the setter.
- property ttl: float
The time to live of the message measured in seconds. Expired messages may be dropped.
- Raise:
MessageException
if there is any Proton error when using the setter.
- property user_id: bytes
The user id of the message creator.
- Raise:
MessageException
if there is any Proton error when using the setter.
- class proton.Terminus(impl)[source]
A source or target for messages.
- property address: str | None
The address that identifies the source or target node
- property capabilities
Capabilities of the source or target.
- property dynamic: bool
Indicates whether the source or target node was dynamically created
- property filter
A filter on a source allows the set of messages transferred over the link to be restricted. The symbol-keyed map represents a’ filter set.
Delivery guarantees¶
For at-most-once, the sender settles the message as soon as it sends it. If the connection is lost before the message is received by the receiver, the message will not be delivered.
For at-least-once, the receiver accepts and settles the message on receipt. If the connection is lost before the sender is informed of the settlement, then the delivery is considered in-doubt and should be retried. This will ensure it eventually gets delivered (provided of course the connection and link can be reestablished). It may mean that it is delivered multiple times though.
Finally, for exactly-once, the receiver accepts the message but doesn’t settle it. The sender settles once it is aware that the receiver accepted it. In this way the receiver retains knowledge of an accepted message until it is sure the sender knows it has been accepted. If the connection is lost before settlement, the receiver informs the sender of all the unsettled deliveries it knows about, and from this the sender can deduce which need to be redelivered. The sender likewise informs the receiver which deliveries it knows about, from which the receiver can deduce which have already been settled.