Skip to content

Instantly share code, notes, and snippets.

@AljoschaMeyer
Created November 4, 2018 17:46
Show Gist options
  • Save AljoschaMeyer/c02d93cb6d78bcfabe026ed116a45ea4 to your computer and use it in GitHub Desktop.
Save AljoschaMeyer/c02d93cb6d78bcfabe026ed116a45ea4 to your computer and use it in GitHub Desktop.

bpmux/rel

Specification for providing the bpmux abstractions over an ordered, reliable, bidirectional communication channel, such as tcp or unix domain sockets.

Bpmux/rel asigns 64 bit identifiers to all entities, so that packets can be "routed" to the correct entities. It also keeps track of whether an entity was created by the endpoint itself (out-entities) or by the peer (in-entities), to prevent trouble when both parties create entities with the same identifier concurrently.

Data gets transmitted in chunks. Each chunk begins with a 1-byte tag, followed by a VarU64 encoding the identifier of an identity, followed by additional bytes whose interpretation depends on the tag. The tag consists of three bits for the type, followed by five bits of flags.

The type indicates what kind of entity the identifier following the tag refers to:

bits type
000 Out-Request
001 In-Request
010 Out-Sink
011 In-Sink
100 Out-Stream
101 In-Stream
110 Duplex
111 Partial

The flags are (from fourth-most-significant to least significant bit):

  • payload
  • credit
  • ping
  • end
  • ack-end

Unless otherwise noted:

  • identifiers are always unsigned 64 bit integers, and when transmitted, they are encoded as VarU64s
  • payloads are byte strings of length up to 2^64 - 1, and are encoded as a VarU64 followed by that many bytes
  • credits are always unsigned 64 bit integers, and when transmitted, they are encoded as VarU64s
  • end-payloads work just like regular payloads, except they are indicated by the end flag

Requests

To send a new request, choose an identifier not in the set of out-requests and send a chunk of type Out-Request. The payload flag must be set, the credit, ping and end flags may be set, and the ack-end flag must not be set. The tag byte is followed by the chosen identifier, followed by the payload, optionally followed by the credit, optionally followed by the end-payload. Add the identifier to the out-requests. If credit was sent, add that much credit to the entry.

To cancel an out-request, send a chunk of type Out-Request, with the end flag set. Mark the corresponding entry in the out-requests as awaiting end acknowledgement.

Upon receiving a packet of type Out-Request, check whether there is already an entry of the correct identifier in your in-requests map. If there is not, and the payload flag is not set, this is an error. If the flag is set, add an entry to the map, with the appropriate credit. If the end flag was set, immediately send back an ack-end chunk of type In-Request and with the identifier.

If there is already an entry for the identifier in your in-requests map, and payload is set, this is an error. Else, update credit if the credit flag is set, or send back an ack-end chunk i the end packet is set.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment