This page describes the protocol used by the Spread-based transport.
Note
Starting with version 0.9 of RSB, the C++ implementation does no longer include the Spread-based transport in the RSB core. Instead, the transport is available as a plugin.
See also
The following configuration options are accepted by the Spread-based transport:
Name Type Comment
+ transport
+-- spread
+---- host string Name of the host running the Spread daemon
+---- port uint Port on which Spread daemon runs
+---- maxfragmentsize uint Maximum Spread message size
+---- tcpnodelay boolean Implementation detail
Data exchanged on the wire by the Spread-based transport is encoded using Google protocol buffers. A Spread message always contains a fragment of a notification elementary communication unit:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | package rsb.protocol;
import "rsb/protocol/Notification.proto";
option java_outer_classname = "FragmentedNotificationType";
// A message which wraps the normal Notification and extends it with
// fragmentation information.
//
// This message is, for example, used in the Spread transport. See
// https://code.cor-lab.org/projects/rsb/wiki/SpreadProtocol for
// information regarding the event <-> notification transformation in
// this case.
message FragmentedNotification {
// The original notification where only currently required fields
// are filled. This means the first fragment contains the full
// meta-data set whereas subsequent FragementedNotifcations only
// carry payload chunks in this field and the event id for
// association.
required Notification notification = 1;
// The number of notifications an event was split into because the
// message size would have been to big for monolithic sending. 1
// indicates a monolithic (self-contained) notification.
required uint32 num_data_parts = 2 [default = 1];
// The index of the current part of a split message. Counting starts with 0
required uint32 data_part = 3 [default = 0];
}
|
package rsb.protocol;
import "rsb/protocol/EventId.proto";
import "rsb/protocol/EventMetaData.proto";
option java_outer_classname = "NotificationType";
// The Notification message is the wire format and serialization
// mechanism used by the RSB Spread transport and other transports.
//
// Notification messages contain
//
// * event routing information,
// * event payloads
// * and optional event meta-data such as timestamps
//
// See
// https://docs.cor-lab.org/rsb-manual/trunk/html/specification-event.html
// for more information regarding events.
message Notification {
/// Identity, transportation and routing information fields
// The unique ID of the event, consisting of the unique id of
// sending participant and the sequence number of the event..
//
// The field number of this required field is generated based on
// the current wire format version number to ensure runtime errors
// for incompatible wire format versions.
required EventId event_id = @WIRE_FORMAT_VERSION_FIELD_NUMBER@;
// The scope to which the encoded event was sent.
optional bytes scope = 6;
// An ASCII-string designating the role of this event within a
// communication pattern. Two such roles could be "REQUEST" and
// "REPLY" in RPC communication.
optional bytes method = 14 [default = ""];
/// Data fields
// An ASCII-string designating the wire schema with which the
// event payload (in the "data" field) has been serialized.
//
// The bytes type has been chosen to avoid UTF-8 de- and encoding.
optional bytes wire_schema = 7;
// The serialized payload of the event.
optional bytes data = 9;
// A collection of id of other events which have in some way
// caused this event to be sent.
repeated EventId causes = 13;
/// Meta-data fields
// meta-data storage
optional EventMetaData meta_data = 15;
}
Because Spread has a message size limit, a single notification may not be sufficient to transport a whole event when the payload is large. Hence, event s may be encoded in several FragmentedNotification s which are sent sequentially. Multiple FragmentedNotification objects are constructed according to the following rules:
The hierarchical bus is created by sending each message to a Spread-group corresponding to its scope as well as to Spread-groups corresponding to all superscopes including the root-scope (/) (In Spread terminology this is called “multigroup mulitcast”).
Example for scope /foo/bar/:
super-scopes(/foo/bar/, include-self? = yes) = /, /foo/, /foo/bar/
Group names are created by applying the following steps to the fully formal scope string representation (including trailing slash):
Example:
/ -> "6666cd76f96956469e7be39d750cc7d\0"
/foo/ -> "4f87be8f6e593d167f5fd1ab238cfc2\0"
/foo/bar/ -> "1c184f3891344400380281315d9e738\0"
The following table explains how the 2D RSB QoS settings are mapped to Spread message types:
Quality | unreliable | reliable |
---|---|---|
unordered | UNRELIABLE_MESS | RELIABLE_MESS |
ordered | FIFO_MESS | FIFO_MESS |
Language | File(s) |
---|---|
C++ | “0.9” branch of https://code.cor-lab.org/git/rsb.git.cpp at src/rsb/transport/spread |
Java | “0.9” branch of https://code.cor-lab.org/git/rsb.git.java at src/rsb/transport/spread |
Python | /../rsb-python/rsb/transport/rsbspread/__init__.py |
Common Lisp | “0.9” branch of https://code.cor-lab.org/git/rsb.git.cl at src/transport/spread |