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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
//! The wire-level vocabulary of a chunked RPC: where a record sits in its
//! run, and how a chunked record comes apart into key, position and part.
//! Reassembling a run is the driver's job (`rpc_driver::ChunkRunAssembler`);
//! this crate holds only what a protocol crate needs to describe its chunked
//! records, so generated bindings keep their single dependency on it.
/// Where one record sits in the run of records that together carry a
/// message too large for one RPC record: its index, from 0, and the run's
/// length. Every record of a run carries the same `count`, each index in
/// `[0, count)` is sent exactly once, and a run always has at least one
/// record, so an empty message is a run of one empty record. The sender may
/// issue a run's calls concurrently and over several connections, so its
/// records can arrive in any order, and the runs of several messages can be
/// in flight at once; the driver's `ChunkRunAssembler` puts them back
/// together.
/// A wire record that is one chunk of a run: it names the message it is
/// part of (its key, such as a batch number), its position in the run, and
/// carries its part of the message's items.
///
/// Protocol crates implement this for each chunked record they define, so a
/// handler passes the record it was called with straight to the driver's
/// `ChunkRunAssembler::push_record`. It lives here so a protocol crate needs
/// no transport dependency to implement it.
///
/// ```
/// use rpc_api::{ChunkPosition, ChunkRecord};
///
/// // The shape a chunked wire record takes: the message it belongs to, its
/// // position in the run, and its slice of the items.
/// struct UpdateChunk {
/// batch: i64,
/// chunk_index: u32,
/// chunk_count: u32,
/// updates: Vec<i64>,
/// }
///
/// impl ChunkRecord for UpdateChunk {
/// type Key = i64;
/// type Part = Vec<i64>;
///
/// fn into_chunk(self) -> (i64, ChunkPosition, Vec<i64>) {
/// let position = ChunkPosition::new(self.chunk_index, self.chunk_count);
/// (self.batch, position, self.updates)
/// }
/// }
///
/// let chunk = UpdateChunk { batch: 7, chunk_index: 1, chunk_count: 2, updates: vec![3] };
/// assert_eq!(chunk.into_chunk(), (7, ChunkPosition::new(1, 2), vec![3]));
/// ```