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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
//! Request lifecycle helpers.
//!
//! Request handling splits into two layers: request-side data
//! manipulation (which fragments are done, which are in error,
//! what error to send) and connection-side plumbing (timeout
//! queues, recv/send done callbacks, peer forwarding).
//!
//! This module owns the data-side helpers; the connection-side
//! helpers land in Stage 9 once the connection FSM exists.
use crateMsgId;
use Msg;
use MsgQueue;
/// Mark `req` as in-error with `error_code` (a libc errno-shaped
/// value) and the matching `dyn_error_code`. The flag is set so the
/// response path can synthesise an error reply on the next pass.
///
/// Returns `true` when the message transitions from healthy to
/// error; subsequent calls are no-ops.
///
/// # Examples
///
/// ```
/// use dynomite::msg::{request, DynErrorCode, Msg, MsgType};
///
/// let mut req = Msg::new(1, MsgType::ReqRedisGet, true);
/// assert!(request::set_error(&mut req, 13, DynErrorCode::PeerHostDown));
/// assert!(req.flags().is_error);
/// assert!(!request::set_error(&mut req, 13, DynErrorCode::PeerHostDown));
/// ```
/// True when the request has been resolved end-to-end: a response
/// has been selected, all fragments are accounted for, and (for
/// fragment vectors) the parent fragment has finished aggregating.
///
/// The connection-coupled propagation pass that walks the client
/// queue and marks every sibling fragment lands in Stage 9; this
/// helper returns the data-shape answer for a single request.
///
/// # Examples
///
/// ```
/// use dynomite::msg::{request, Msg, MsgType};
///
/// let mut req = Msg::new(1, MsgType::ReqRedisGet, true);
/// assert!(!request::is_done(&req));
/// req.set_selected_rsp(Some(2));
/// assert!(request::is_done(&req));
/// ```
/// True when the request is in error: either marked directly or
/// flagged through fragment-error propagation.
///
/// # Examples
///
/// ```
/// use dynomite::msg::{request, DynErrorCode, Msg, MsgType};
///
/// let mut req = Msg::new(1, MsgType::ReqRedisGet, true);
/// assert!(!request::is_error(&req));
/// request::set_error(&mut req, 13, DynErrorCode::PeerHostDown);
/// assert!(request::is_error(&req));
/// ```
/// Drain `from` of every request whose `selected_rsp` matches `id`
/// and forward them to `to`.
///
/// This is the data-shape building block the connection-level
/// `req_send_next` / `req_send_done` functions consume; it lets
/// tests exercise the sibling-walk without standing up the full
/// connection FSM.
///
/// # Examples
///
/// ```
/// use dynomite::msg::{request, Msg, MsgQueue, MsgType};
///
/// let mut a = MsgQueue::new();
/// let mut b = MsgQueue::new();
/// let mut m = Msg::new(1, MsgType::ReqRedisGet, true);
/// m.set_selected_rsp(Some(99));
/// a.push_back(m);
/// request::move_completed(&mut a, &mut b, 99);
/// assert!(a.is_empty());
/// assert_eq!(b.len(), 1);
/// ```