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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
//! Memcached repair surface.
//!
//! In the reference engine, every `memcache_*_repair` function and
//! `memcache_reconcile_responses` either returns `DN_OK` after doing
//! nothing or, in the reconciliation case, returns the first
//! response when consistency is `DC_QUORUM` and an error response
//! otherwise. Memcached responses are not rewritten, so the
//! "rewrite with metadata" surface is intentionally empty.
//!
//! The Rust port reproduces this exactly. Each function below
//! mirrors the reference shape for parity with the Redis surface
//! and so the cluster layer can call into either protocol via the
//! same trait set.
use crateMsgType;
use crate;
/// Repair-surface result type. Matches the Redis repair return
/// shape so the cluster dispatcher can use a single
/// `Result<RepairOutcome, RepairError>` discriminant.
/// Errors the Memcached repair surface can raise. Memcached has no
/// live failure modes; the variant exists for parity with the
/// Redis surface.
/// Memcached query rewrite. The reference engine returns `DN_OK`
/// without producing a rewritten message. The Rust port returns
/// [`RepairOutcome::NoOp`] for the same reason.
///
/// # Examples
///
/// ```
/// use dynomite::msg::{Msg, MsgType};
/// use dynomite::proto::memcache::memcache_rewrite_query;
///
/// let mut m = Msg::new(0, MsgType::ReqMcSet, true);
/// let outcome = memcache_rewrite_query(&mut m).unwrap();
/// matches!(outcome, dynomite::proto::memcache::repair::RepairOutcome::NoOp);
/// ```
/// Memcached query rewrite with timestamp metadata. The reference
/// engine returns `DN_OK` without rewriting; the Rust port matches.
///
/// # Examples
///
/// ```
/// use dynomite::msg::{Msg, MsgType};
/// use dynomite::proto::memcache::memcache_rewrite_query_with_timestamp_md;
///
/// let mut m = Msg::new(0, MsgType::ReqMcSet, true);
/// assert!(memcache_rewrite_query_with_timestamp_md(&mut m).is_ok());
/// ```
/// Build a repair query for a Memcached response set. The reference
/// engine returns `DN_OK` without producing a repair query. The
/// Rust port returns [`RepairOutcome::NoOp`].
///
/// # Examples
///
/// ```
/// use dynomite::msg::{Msg, MsgType, ResponseMgr};
/// use dynomite::proto::memcache::memcache_make_repair_query;
///
/// let req = Msg::new(0, MsgType::ReqMcGet, true);
/// let mgr = ResponseMgr::new(&req, 1, None);
/// assert!(memcache_make_repair_query(&mgr).is_ok());
/// ```
/// Clear repair metadata for a key. The reference engine returns
/// `DN_OK` without producing a cleanup message. The Rust port
/// matches.
///
/// # Examples
///
/// ```
/// use dynomite::msg::{Msg, MsgType};
/// use dynomite::proto::memcache::memcache_clear_repair_md_for_key;
///
/// let mut req = Msg::new(0, MsgType::ReqMcSet, true);
/// assert!(memcache_clear_repair_md_for_key(&mut req).is_ok());
/// ```
/// Reconcile responses across replicas. The reference engine picks
/// the first response under `DC_QUORUM` and otherwise returns an
/// error response. The Rust port reproduces both arms by reporting
/// the chosen index plus an optional fresh error response.
///
/// # Examples
///
/// ```
/// use dynomite::msg::{ConsistencyLevel, Msg, MsgType, ResponseMgr};
/// use dynomite::proto::memcache::memcache_reconcile_responses;
///
/// let mut req = Msg::new(0, MsgType::ReqMcGet, true);
/// req.set_consistency(ConsistencyLevel::DcQuorum);
/// let mut mgr = ResponseMgr::new(&req, 3, None);
/// // Submit one response (Stage 9 plumbing supplies the responses
/// // in real use).
/// let outcome = memcache_reconcile_responses(&mgr, ConsistencyLevel::DcQuorum);
/// matches!(outcome, dynomite::proto::memcache::repair::ReconcileOutcome::PickFirst);
/// ```
/// Outcome of [`memcache_reconcile_responses`].