Wire Representation
If you don't care about efficiency or serialization, skip this section. Wire representation is how your protocol looks like on the wire.
It's important to know about the wire representation and channel representation of the protocols you build on top of Canary, since ALL distributed systems and communications have a channel representation (what is sent through the wire and what is received through the wire in order) and a wire representation (what is sent through the wire and received through the wire but separated) even those that aren't built on top of Canary.
Wire and channel representations also help debug distributed systems and also help know which types are equivalent on the wire ( e.g. &str and String have an equivalent wire representation ).
The differences between the wire representation and channel representation is that the wire representation is divided into inbound (receiving) wire representation and outbound (sending) wire representation.
An example wire representation:
send:
# position 1
1 u16,
# position 3
3 u16,
receive:
# position 2
2 u16,
This outbound wire representation looks like this on the wire:
(outbound)
1 3
-> 0x0 0x0
(inbound)
2
<- 0x0
Common wire-equivalent types are:
Vec<T>
and[T]
String
andstr
u16
and[u8; 2]
u32
and[u8; 4]
u64
and[u8; 8]
Another example of a wire representation:
send:
1 [u8; 2],
2 String,
receive:
3 Vec<u16>,
4 u16
Astute readers may have noticed that we run into a problem when trying to
represent this wire representation:
What about String
and Vec<u8>
?
They are dynamically sized, so their length is sent first (as an u64),
and then they're serialized and sent, so they look like this:
->
1 # [u8; 2]
0x0 0x0
2 # length of serialized object
0x0 0x0 0x0 0x0
# a unit struct represents a dynamically sized object
()
<-
3 # Vec<u16>, dynamically sized
0x0 0x0 0x0 0x0 ()
4 0x0
A condensed version of this wire representation looks like this:
->
1 0x0 0x0
2 0x0 0x0 0x0 0x0 ()
<-
3 0x0 0x0 0x0 0x0 ()
4 0x0
Currently due to simplicity, Canary sends all objects (even wire statically-sized-types) as dynamically sized. This means that there is space for improvement, but it is still sufficiently efficient for most use cases.
NOTE ABOUT TYPES: Sending and receiving non-equivalent wire represented types can lead to messaging problems which can be really hard to debug.