...continuation from previous post
Connect to Plugin
For plugin a
to establish a connection to plugin b
, plugin a
opens a duplex with a payload consisting of the byte 0000_0000
followed by <length_uint8><name>
of plugin b
. If a
has already established a connection to b
that hasn't been closed/canceled in both direction, the server must directly cancel and close the duplex with a zero-length payload. Else, the server must allocate enough memory for two 64 bit integers and two buffers of bytes for caching data, each of size at least one byte. If it fails to do so, it must both close and cancel the duplex with the byte 0000_0000
as the payload. If memory allocation succeeded, the server then opens a duplex to plugin b
, with a payload consisting of the byte 0000_0000
followed by the <length_uint8><name><version_uint16>
of plugin a
.
All pings sent by a
get relayed along that channel. All credit given by a
is buffered into one of the 64 bit integer the server allocated. Likewise, pings by b
are forwarded and credit given by b
is buffered as well.
Plugin b
can deny the connection by closing and cancelling the duplex with a zero-length payload. In that case, the server must close and cancel the duplex with a
with the byte 0000_0001
as the payload. Plugin b
can accept the connection by sending a zero-length message down the duplex. In that case, the server must send a zero-length message down the duplex it shared with a
. It then sends all buffered credit to a
and b
respectively. The logical connection between a
and b
is now established, consisting of the two duplexes.
After the connection has been established, the server forwards all messages, heartbeat pings, heartbeat pongs, and credit along the duplexes. To the plugins, this looks like a direct connection between them. There is a situation however where the server may choose to not directly relay all credit. Imagine a setting where there is a very fast connection between a
and the server, but a very slow connection between the server and b
. Furthermore assume that b
gives a lot of credit to a
. a
sends a lot of data, but the server can not relay it fast enough to b
, so it has to buffer data. In this setting, b
would effectively determine how much data the server has to buffer. To prevent this, the server can simply put an upper limit to the credit it hands to a
, and store any excess credit given by b
in one of the 64 bit integers. When more data could be sent from the server to b
, it can then send more credit to a
, removing it from the 64 bit integer. The server should use a scheme that is more efficient than sending credit whenever data could be sent, as that might result in a lot of credit data being transmitted.
If one of the plugins cancels/closes parts of the connection, the server prepends a byte 0000_0000
to the payload before relaying it.
Server Behavior Upon Plugin Disconnection
When plugin foo
sends a disconnection message, or the connection to the server is closed or errors, the server must perform the following cleanup work (only once per plugin):
- notify all connection streams
- for any connections between
foo
and other plugins, cancel and close the duplex between server and the remaining plugin, both with the byte0000_0001
as the payload.
Handling Unexpected Messages
If the plugin sends any data to the server that does not fit into one of the flows described above, the server must do the following:
- if it is a message, ignore it
- if it is a request, cancel it with a zero-length payload
- if it is a sink, cancel it with a zero-length payload
- if it is a stream, close it with a zero-length payload
- if it is a duplex, cancel and close it with a zero-length payload
This allows backwards-compatible protocol extensions. Clients can use these to check whether some feature that might be added to min-bus is unsupported by the server, without disrupting the connection.