std/amqp
On this page
Index
- type
Value - type
AmqpErr - type
Role - type
SenderSettleMode - type
ReceiverSettleMode - type
WireError - type
DeliveryState - type
Source - type
Target - type
Open - type
Begin - type
Attach - type
Flow - type
Transfer - type
Disposition - type
Detach - type
End - type
Close - type
SaslMechanisms - type
SaslInit - type
SaslChallenge - type
SaslResponse - type
SaslOutcome - type
FrameBody - type
Frame - type
Sasl - type
ConnOptions - type
Transport - type
ConnState - type
Connection- method
Connection.peer_container_id - method
Connection.peer_max_frame_size - method
Connection.peer_channel_max - method
Connection.peer_idle_timeout_ms - method
Connection.peer_properties - method
Connection.keepalive - method
Connection.send - method
Connection.recv - method
Connection.close - method
Connection.abort - method
Connection.begin - method
Connection.end_session - method
Connection.new_sender - method
Connection.new_receiver
- method
- type
SessionOptions - type
Session - type
Header - type
Properties - type
Body - type
Message - type
SessState - type
Delivery - type
LinkState - type
SenderOptions - type
ReceiverOptions - type
Sender- method
Sender.send - method
Sender.close - method
Sender.remote_attach
- method
- type
Receiver- method
Receiver.receive - method
Receiver.remote_attach - method
Receiver.issue_credit - method
Receiver.drain - method
Receiver.accept - method
Receiver.reject - method
Receiver.release - method
Receiver.modify - method
Receiver.close
- method
- fn
encode - fn
decode - fn
encode_frame - fn
decode_frame - fn
dial - fn
encode_message - fn
decode_message - fn
cbs_put_token
Types
Value
enum Value {
Null
Bool(v: Bool)
UByte(v: UInt8)
UShort(v: UInt16)
UInt(v: UInt32)
ULong(v: UInt64)
Byte(v: Int8)
Short(v: Int16)
Int(v: Int32)
Long(v: Int64)
Float(v: Float32)
Double(v: Float)
Decimal32(bits: UInt32)
Decimal64(bits: UInt64)
Decimal128(bits: Bytes)
Char(v: Rune)
Timestamp(ms: Int)
Uuid(bytes: Bytes)
Binary(v: Bytes)
Str(v: Str)
Symbol(v: Str)
List(items: List[Value])
Map(pairs: List[(Value, Value)])
Array(items: List[Value])
Described(descriptor: Value, value: Value)
}An AMQP 1.0 value (section 1.6 of the specification): the primitive types, the compound types, and a described value.
AmqpErr
enum AmqpErr {
Decode(msg: Str)
Encode(msg: Str)
Net(msg: Str)
Protocol(msg: Str)
Peer(error: WireError)
Auth(code: Int, msg: Str)
}Role
enum Role {
Sender
Receiver
}SenderSettleMode
enum SenderSettleMode {
Unsettled
Settled
Mixed
}sender-settle-mode (ubyte)
ReceiverSettleMode
enum ReceiverSettleMode {
First
Second
}receiver-settle-mode (ubyte)
WireError
struct WireError {
condition: Str
description: Str = ""
info: List[(Str, Value)] = []
}An AMQP error: a symbolic condition (amqp:link:detach-forced), text,
and a map of details.
DeliveryState
enum DeliveryState {
Received(section_number: UInt32, section_offset: UInt64)
Accepted
Rejected(error: WireError?)
Released
Modified(delivery_failed: Bool, undeliverable_here: Bool, annotations: List[(Value, Value)])
}The outcome or state of a delivery (section 3.4).
Source
struct Source {
address: Str = ""
durable: Int = 0
expiry_policy: Str = ""
timeout: Int = 0
dynamic: Bool = false
dynamic_node_properties: List[(Str, Value)] = []
distribution_mode: Str = ""
filter: List[(Str, Value)] = []
default_outcome: Value = Value.Null
outcomes: List[Str] = []
capabilities: List[Str] = []
}A link’s source (section 3.5.3). Fields typed Int that hold an unsigned wire value (durable, timeout, max_frame_size, channel_max, handle_max, initial_delivery_count, max_message_size) must be in range for the wire type (0 to 2^32-1, 2^16-1, 2^63-1); encode_frame refuses one outside it.
Target
struct Target {
address: Str = ""
durable: Int = 0
expiry_policy: Str = ""
timeout: Int = 0
dynamic: Bool = false
dynamic_node_properties: List[(Str, Value)] = []
capabilities: List[Str] = []
}A link’s target (section 3.5.4).
Open
struct Open {
container_id: Str
hostname: Str = ""
max_frame_size: Int = 4294967295
channel_max: Int = 65535
idle_timeout_ms: Int = 0
outgoing_locales: List[Str] = []
incoming_locales: List[Str] = []
offered_capabilities: List[Str] = []
desired_capabilities: List[Str] = []
properties: List[(Str, Value)] = []
}Begin
struct Begin {
remote_channel: UInt16?
next_outgoing_id: UInt32
incoming_window: UInt32
outgoing_window: UInt32
handle_max: Int = 4294967295
offered_capabilities: List[Str] = []
desired_capabilities: List[Str] = []
properties: List[(Str, Value)] = []
}Attach
struct Attach {
name: Str
handle: UInt32
role: Role
sender_settle_mode: SenderSettleMode?
receiver_settle_mode: ReceiverSettleMode?
source: Source?
target: Target?
unsettled: List[(Bytes, DeliveryState?)] = []
incomplete_unsettled: Bool = false
initial_delivery_count: Int = 0
max_message_size: Int = 0
offered_capabilities: List[Str] = []
desired_capabilities: List[Str] = []
properties: List[(Str, Value)] = []
}Flow
struct Flow {
next_incoming_id: UInt32?
incoming_window: UInt32
next_outgoing_id: UInt32
outgoing_window: UInt32
handle: UInt32?
delivery_count: UInt32?
link_credit: UInt32?
available: UInt32?
drain: Bool = false
echo: Bool = false
properties: List[(Str, Value)] = []
}Transfer
struct Transfer {
handle: UInt32
delivery_id: UInt32?
delivery_tag: Bytes = b""
message_format: UInt32?
settled: Bool = false
more: Bool = false
receiver_settle_mode: ReceiverSettleMode?
state: DeliveryState?
resume: Bool = false
aborted: Bool = false
batchable: Bool = false
payload: Bytes = b""
}Disposition
struct Disposition {
role: Role
first: UInt32
last: UInt32?
settled: Bool = false
state: DeliveryState?
batchable: Bool = false
}Detach
struct Detach {
handle: UInt32
closed: Bool = false
error: WireError?
}End
struct End {
error: WireError?
}Close
struct Close {
error: WireError?
}SaslMechanisms
struct SaslMechanisms {
mechanisms: List[Str]
}SaslInit
struct SaslInit {
mechanism: Str
initial_response: Bytes = b""
hostname: Str = ""
}SaslChallenge
struct SaslChallenge {
challenge: Bytes
}SaslResponse
struct SaslResponse {
response: Bytes
}SaslOutcome
struct SaslOutcome {
code: UInt8
additional_data: Bytes = b""
}sasl-code (ubyte): 0 ok, 1 auth, 2 sys, 3 sys-perm, 4 sys-temp
FrameBody
enum FrameBody {
Open(v: Open)
Begin(v: Begin)
Attach(v: Attach)
Flow(v: Flow)
Transfer(v: Transfer)
Disposition(v: Disposition)
Detach(v: Detach)
End(v: End)
Close(v: Close)
SaslMechanisms(v: SaslMechanisms)
SaslInit(v: SaslInit)
SaslChallenge(v: SaslChallenge)
SaslResponse(v: SaslResponse)
SaslOutcome(v: SaslOutcome)
Empty
}The body of a frame.
Frame
struct Frame {
channel: UInt16
body: FrameBody
}A frame: the channel it is for and its body. SASL frames are on channel 0.
Sasl
enum Sasl {
None
Plain(user: Str, password: Str)
Anonymous
}How to authenticate during the SASL exchange (section 5.3).
ConnOptions
struct ConnOptions {
container_id: Str = ""
hostname: Str = ""
max_frame_size: Int = 65536
channel_max: Int = 65535
idle_timeout_ms: Int = 0
properties: List[(Str, Value)] = []
sasl: Sasl = Sasl.None
tls_roots: tls.Roots? = None
tls_verify: tls.Verify = tls.Verify.Full
clock: Clock? = None
timeout_ms: Int = 0
}Transport
enum Transport {
Plain(c: Conn)
Tls(t: tls.TlsConn)
}The transport, plain or TLS (as std/smtp’s Link).
ConnState
struct ConnState {
link: Transport
buf: Bytes = b""
max_frame_size: Int = 65536
peer_max_frame_size: Int = 65536
peer_channel_max: Int = 65535
peer_idle_timeout_ms: Int = 0
peer_container_id: Str = ""
peer_properties: List[(Str, Value)] = []
channels: List[Int] = []
pending: List[Frame] = []
closed: Bool = false
clock: Clock? = None
timeout_ms: Int = 0
idle_timeout_ms: Int = 0
last_recv_ms: Int = 0
last_send_ms: Int = 0
broken: AmqpErr? = None
mux: Bool = false
closing: Bool = false
close_done: Bool = false
close_err: AmqpErr? = None
waiters: List[Chan[Bool]] = []
sess: List[SessState] = []
links: List[LinkState] = []
}A connection’s state. Internal: use the methods of Connection.
Connection
struct Connection {
st: Mutex[ConnState]
}An open AMQP connection. A handle: copies share the connection, and its methods serialize on it.
Connection.peer_container_id
fn (c: Connection) peer_container_id() -> StrThe peer’s container id from its Open.
Connection.peer_max_frame_size
fn (c: Connection) peer_max_frame_size() -> IntThe largest frame the peer accepts, in bytes.
Connection.peer_channel_max
fn (c: Connection) peer_channel_max() -> IntThe largest channel number usable (the lower of both sides’ channel-max).
Connection.peer_idle_timeout_ms
fn (c: Connection) peer_idle_timeout_ms() -> IntThe peer’s advertised idle timeout in milliseconds, 0 for none.
Connection.peer_properties
fn (c: Connection) peer_properties() -> List[(Str, Value)]The peer’s Open properties.
Connection.keepalive
fn (c: Connection) keepalive(g: task.Group) -> () ! AmqpErr uses (net.dial, clock)Starts a task in g that keeps the connection alive while no call is running: it sends an
empty frame at half the peer’s idle timeout, reads and applies frames that arrive, and fails
the connection (later calls return the error) when the peer is silent for idle_timeout_ms.
While it runs it is the only reader: calls that wait (a receive, a send waiting for credit)
wait on their own channel without the connection lock, so tasks can receive on several links,
send and settle at the same time; recv is refused. It needs ConnOptions.clock and ends when
g is cancelled or the connection is closed. Without it, calls read while they wait.
Connection.send
fn (c: Connection) send(f: Frame) -> () ! AmqpErr uses (net.dial, clock)Writes one frame, as encode_frame’s bytes.
Connection.recv
fn (c: Connection) recv() -> Frame ! AmqpErr uses (net.dial, clock)The next frame from the peer (an empty frame is returned as FrameBody.Empty).
Connection.close
fn (c: Connection) close(error: WireError? = None) -> () ! AmqpErr uses (net.dial, clock)Sends Close and waits for the peer’s Close; a Close carrying an error is Peer.
Connection.abort
fn (c: Connection) abort()Drops the transport without the Close exchange.
Connection.begin
fn (c: Connection) begin(opts: SessionOptions = SessionOptions{}) -> Session ! AmqpErr uses (net.dial, clock)Begins a session on the lowest free channel and waits for the peer’s Begin.
Connection.end_session
fn (c: Connection) end_session(s: Session, error: WireError? = None) -> () ! AmqpErr uses (net.dial, clock)Ends the session (End, then the peer’s End); frames for other channels read while waiting stay queued for recv.
Connection.new_sender
fn (c: Connection) new_sender(s: Session, target: Str, opts: SenderOptions = SenderOptions{}) -> Sender ! AmqpErr uses (net.dial, clock)Attaches a sending link on session s to target and waits for the peer’s Attach. A peer that
refuses the link answers with a Detach carrying an error, which is Peer.
Connection.new_receiver
fn (c: Connection) new_receiver(s: Session, source: Str, opts: ReceiverOptions = ReceiverOptions{}) -> Receiver ! AmqpErr uses (net.dial, clock)Attaches a receiving link on session s from source and grants the initial credit.
SessionOptions
struct SessionOptions {
incoming_window: Int = 2048
outgoing_window: Int = 2048
handle_max: Int = 4294967295
}Session
struct Session {
channel: Int
remote_channel: Int = 0
next_outgoing_id: Int = 0
remote_incoming_window: Int = 0
remote_outgoing_window: Int = 0
remote_next_outgoing_id: Int = 0
incoming_window: Int
outgoing_window: Int
handle_max: Int
remote_handle_max: Int = 0
}A begun session: its channel and the windows both sides announced.
Header
struct Header {
durable: Bool = false
priority: Int = 4
ttl_ms: Int = 0
first_acquirer: Bool = false
delivery_count: Int = 0
}The header section: delivery details.
Properties
struct Properties {
message_id: Value = Value.Null
user_id: Bytes = b""
to: Str? = None
subject: Str? = None
reply_to: Str? = None
correlation_id: Value = Value.Null
content_type: Str? = None
content_encoding: Str? = None
absolute_expiry_ms: Int? = None
creation_ms: Int? = None
group_id: Str? = None
group_sequence: Int? = None
reply_to_group_id: Str? = None
}The properties section: standard properties of the message.
Body
enum Body {
Empty
Data(sections: List[Bytes])
Sequence(sections: List[List[Value]])
Value(v: Value)
}The body: one or more data sections, one or more sequence sections, or one value.
Message
struct Message {
header: Header? = None
delivery_annotations: List[(Value, Value)]? = None
annotations: List[(Value, Value)]? = None
properties: Properties? = None
app_properties: List[(Str, Value)]? = None
body: Body = Body.Empty
footer: List[(Value, Value)]? = None
}A message: the sections of the bare and annotated message. A None section is not written; a
Some section is written even when empty (go-amqp’s rule for a non-nil map).
SessState
struct SessState {
channel: Int
next_outgoing_id: Int = 0
next_incoming_id: Int = 0
incoming_window: Int
initial_incoming_window: Int
remote_incoming_window: Int = 0
ended: Bool = false
next_handle: Int = 0
sending: Bool = false
}A session’s flow control state. Internal: use the methods of Connection.
Delivery
struct Delivery {
message: Message
id: Int
tag: Bytes
settled: Bool
link: Int
}A completed incoming delivery.
LinkState
struct LinkState {
id: Int
name: Str
channel: Int
handle: Int
role: Role
remote_handle: Int = -1
attached: Bool = false
refused: Bool = false
detached: Bool = false
error: WireError? = None
peer_max_message_size: Int = 0
delivery_count: Int = 0
credit: Int = 0
credit_target: Int = 1
remote_attach: Attach? = None
draining: Bool = false
second: Bool = false
waiting: List[Int] = []
acks: List[(Int, DeliveryState?)] = []
tag_counter: Int = 0
results: List[(Int, DeliveryState?)] = []
partial: Bytes = b""
partial_active: Bool = false
partial_id: Int = 0
partial_tag: Bytes = b""
partial_settled: Bool = false
unsettled: List[Int] = []
inbox: List[Delivery] = []
}A link’s state. Internal: use Sender and Receiver.
SenderOptions
struct SenderOptions {
name: Str = ""
settle_mode: SenderSettleMode? = None
source: Str = ""
max_message_size: Int = 0
properties: List[(Str, Value)] = []
capabilities: List[Str] = []
target_capabilities: List[Str] = []
desired_capabilities: List[Str] = []
}ReceiverOptions
struct ReceiverOptions {
name: Str = ""
credit: Int = 1
settle_mode: ReceiverSettleMode? = None
sender_settle_mode: SenderSettleMode? = None
target: Str = ""
filters: List[(Str, Value)] = []
max_message_size: Int = 0
properties: List[(Str, Value)] = []
capabilities: List[Str] = []
source_capabilities: List[Str] = []
desired_capabilities: List[Str] = []
}Sender
struct Sender {
conn: Connection
id: Int
name: Str
target: Str
}A sending link; a handle over its connection.
Sender.send
fn (x: Sender) send(m: Message, settled: Bool = false, message_format: Int = 0) -> DeliveryState? ! AmqpErr uses (net.dial, clock)Sends the message and returns the peer’s outcome for it (Accepted, Rejected, …), waiting for
link credit, session window and the settlement. With settled true the transfer is sent
pre-settled and the result is None right away. message_format is the Transfer’s message-format
(0 for an AMQP message; Azure Service Bus batches use 0x80013700, a message whose data sections are
each an encoded message).
Sender.close
fn (x: Sender) close(error: WireError? = None) -> () ! AmqpErr uses (net.dial, clock)Detaches the link (with closed set) and waits for the peer’s Detach.
Sender.remote_attach
fn (x: Sender) remote_attach() -> Attach?Receiver
struct Receiver {
conn: Connection
id: Int
name: Str
source: Str
}A receiving link; a handle over its connection.
Receiver.receive
fn (r: Receiver) receive(timeout_ms: Int = 0) -> Delivery ! AmqpErr uses (net.dial, clock)The next complete message, topping up credit as needed.
Receiver.remote_attach
fn (r: Receiver) remote_attach() -> Attach?The peer’s Attach frame for this link (None until it arrives; new_receiver returns after it did):
its source with the filters the peer applied (Service Bus echoes com.microsoft:session-filter
with the session it chose), its target and its properties (com.microsoft:locked-until-utc).
Receiver.issue_credit
fn (r: Receiver) issue_credit(n: Int) -> () ! AmqpErr uses (net.dial, clock)Grants the peer n more credit (a Flow with the link credit raised by n). With
ReceiverOptions.credit 0 this is the only credit the link has.
Receiver.drain
fn (r: Receiver) drain(timeout_ms: Int = 0) -> List[Delivery] ! AmqpErr uses (net.dial, clock)Asks the peer to use up or give up the credit (a Flow with drain set), waits for its answer and
returns every delivery that arrived before it, oldest first; the link then has no credit.
timeout_ms bounds the wait (0 for none; it needs ConnOptions.clock).
Receiver.accept
fn (r: Receiver) accept(d: Delivery) -> () ! AmqpErr uses (net.dial, clock)Settles the delivery with the outcome. With ReceiverSettleMode.Second the outcome is sent
unsettled and the call waits for the peer’s settlement: a peer that refuses it (a Rejected state
with an error, such as Service Bus’s com.microsoft:message-lock-lost) makes the call Peer.
Receiver.reject
fn (r: Receiver) reject(d: Delivery, error: WireError? = None) -> () ! AmqpErr uses (net.dial, clock)Receiver.release
fn (r: Receiver) release(d: Delivery) -> () ! AmqpErr uses (net.dial, clock)Receiver.modify
fn (r: Receiver) modify(d: Delivery, delivery_failed: Bool = true, undeliverable_here: Bool = false, annotations: List[(Str, Value)] = []) -> () ! AmqpErr uses (net.dial, clock)annotations are the Modified outcome’s message-annotations to apply (Go’s properties to modify;
the keys are symbols).
Receiver.close
fn (r: Receiver) close(error: WireError? = None) -> () ! AmqpErr uses (net.dial, clock)Detaches the link (with closed set) and waits for the peer’s Detach.
Functions
encode
fn encode(v: Value) -> Bytes ! AmqpErrThe encoding of v with the smallest constructors go-amqp’s encoder picks (smalluint, list8, str8 and so on).
decode
fn decode(b: Bytes) -> (Value, Int) ! AmqpErrThe value at the start of b and the number of bytes it took.
encode_frame
fn encode_frame(f: Frame) -> Bytes ! AmqpErrThe frame as bytes: the 8 byte header (size, data offset 2, type 0 for AMQP and 1 for SASL, channel) and the body.
decode_frame
fn decode_frame(b: Bytes, max_size: Int = 4294967295) -> (Frame, Int) ! AmqpErrThe frame at the start of b and the bytes it took; max_size is the
largest frame size accepted (a larger one is a Decode error).
dial
fn dial(net: Net, addr: Str, opts: ConnOptions = ConnOptions{}) -> Connection ! AmqpErr uses (net.dial, clock)Connects to addr (host:port, amqp://host[:port] or amqps://host[:port]; ports default
to 5672 and 5671; amqps runs TLS first), runs the SASL exchange when opts.sasl is not None,
and exchanges the Open frames.
encode_message
fn encode_message(m: Message) -> Bytes ! AmqpErrThe message as the bytes of a transfer’s payload.
decode_message
fn decode_message(b: Bytes) -> Message ! AmqpErrThe message in b (all of it); a section out of the specification’s order is accepted, a repeated header, properties or annotations section, or mixed body kinds, is a Decode error.
cbs_put_token
fn cbs_put_token(c: Connection, s: Session, audience: Str, token: Str, token_type: Str = "servicebus.windows.net:sastoken", expiry_ms: Int = 0, expiration: Value? = None) -> () ! AmqpErr uses (net.dial, clock)Authorizes the connection with a token: sends a put-token request on a $cbs sender and reads the
answer on a $cbs receiver (reply address cbs), then detaches both links. token_type is
servicebus.windows.net:sastoken for a SAS token and jwt for an Entra ID one. A status code
outside 200 to 299 is Peer with the condition amqp:unauthorized-access and the description the
server gave. expiry_ms (milliseconds since the Unix epoch) is sent as expiration when not 0.
expiration, when given, is sent as the expiration property as it is and wins over expiry_ms (Go’s clients send
a string of Unix seconds).