You are reading content from Scuttlebutt
@aljoscha %H2gIVty6N6Y/fr/vfHYsFLdlMSVht1UkRXQpmNaHa10=.sha256
Re: %eOgrGRIfP

...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 byte 0000_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.

Join Scuttlebutt now