fast_rpc/lib.rs
1// Copyright 2019 Joyent, Inc.
2
3//! Fast: A simple RPC protcol used by Joyent products
4//!
5//! Fast is a simple RPC protocol used in
6//! Joyent's[Triton](http://github.com/joyent/triton) and
7//! [Manta](https://github.com/joyent/manta) systems, particularly in the
8//! [Moray](https://github.com/joyent/moray) and
9//! [Boray](https://github.com/joyent/boray) components.
10//!
11//! Protocol overview
12//!
13//! The Fast protocol is intended for use with TCP. Typically, a Fast server
14//! listens for TCP connections on a well-known port, and Fast clients connect
15//! to the server to make RPC requests. Clients can make multiple connections
16//! to the server, but each connection represents a logically separate
17//! client. Communication between client and server consist of discrete
18//! _messages_ sent over the TCP connection.
19//!
20//! Fast protocol messages have the following structure:
21//!
22//! <img src="../../../docs/fastpacket.svg" width="100%" height="100%">
23//!
24//! * VERSION 1-byte integer. The only supported value is "1".
25//!
26//! * TYPE 1-byte integer. The only supported value is TYPE_JSON (0x1),
27//! indicating that the data payload is an encoded JSON object.
28//!
29//! * STATUS 1-byte integer. The only supported values are:
30//!
31//! * STATUS_DATA 0x1 indicates a "data" message
32//!
33//! * STATUS_END 0x2 indicates an "end" message
34//!
35//! * STATUS_ERROR 0x3 indicates an "error" message
36//!
37//! * MSGID0...MSGID3 4-byte big-endian unsigned integer, a unique identifier
38//! for this message.
39//!
40//! * CRC0...CRC3 4-byte big-endian unsigned integer representing the CRC16
41//! value of the data payload
42//!
43//! * DLEN0...DLEN4 4-byte big-endian unsigned integer representing the number
44//! of bytes of data payload that follow
45//!
46//! * DATA0...DATAN Data payload. This is a JSON-encoded object (for TYPE =
47//! TYPE_JSON). The encoding length in bytes is given by the
48//! DLEN0...DLEN4 bytes.
49//!
50//! ### Status
51//!
52//! There are three allowed values for `status`:
53//!
54//! |Status value | Status name | Description |
55//! |------------ | ----------- | ----------- |
56//! | `0x1` | `DATA` | From clients, indicates an RPC request. From servers, indicates one of many values emitted by an RPC call.|
57//! | `0x2` | `END` | Indicates the successful completion of an RPC call. Only sent by servers. |
58//! | `0x3` | `ERROR` | Indicates the failed completion of an RPC call. Only sent by servers. |
59//!
60//! ### Message IDs
61//!
62//! Each Fast message has a message id, which is scoped to the Fast
63//! connection. These are allocated sequentially from a circular 31-bit space.
64//!
65//! ### Data payload
66//!
67//! For all messages, the `data` field contains properties:
68//!
69//! | Field | Type | Purpose |
70//! | -------- | ----------------- | ------- |
71//! | `m` | object | describes the RPC method being invoked |
72//! | `m.name` | string | name of the RPC method being invoked |
73//! | `m.uts` | number (optional) | timestamp of message creation, in microseconds since the Unix epoch |
74//! | `d` | object or array | varies by message status |
75//!
76//! ### Messaging Scenarios
77//!
78//! Essentially, there are only four messaging scenarios with Fast:
79//!
80//! **Client initiates an RPC request.** The client allocates a new message
81//! identifier and sends a `DATA` message with `data.m.name` set to the name of
82//! the RPC method it wants to invoke. Arguments are specified by the array
83//! `data.d`. Clients may issue concurrent requests over a single TCP
84//! connection, provided they do not re-use a message identifier for separate
85//! requests.
86//!
87//! **Server sends data from an RPC call.** RPC calls may emit an arbitrary
88//! number of values back to the client. To emit these values, the server sends
89//! `DATA` messages with `data.d` set to an array of non-null values to be
90//! emitted. All `DATA` messages for the same RPC request have the same message
91//! identifier that the client included in its original `DATA` message that
92//! initiated the RPC call.
93//!
94//! **Server completes an RPC call successfully.** When an RPC call completes
95//! successfully, the server sends an `END` event having the same message
96//! identifier as the one in the client's original `DATA` message that initiated
97//! the RPC call. This message can contain data as well, in which case it should
98//! be processed the same way as for a DATA message.
99//!
100//! **Server reports a failed RPC call.** Any time before an `END` message is
101//! generated for an RPC call, the server may send an `ERROR` message having the
102//! same message identifier as the one in the client's original `DATA` message
103//! that initiated the RPC call.
104//!
105//! By convention, the `m` fields (`m.name` and `m.uts`) are populated for all
106//! server messages, even though `m.name` is redundant.
107//!
108//! The RPC request begins when the client sends the initial `DATA` message.
109//! The RPC request is finished when the server sends either an `ERROR` or `END`
110//! message for that request. In summary, the client only ever sends one
111//! message for each request. The server may send any number of `DATA` messages
112//! and exactly one `END` or `ERROR` message.
113
114#![allow(missing_docs)]
115
116pub mod client;
117pub mod protocol;
118pub mod server;