pub struct ResponseMgr { /* private fields */ }Expand description
Per-DC response aggregator.
The manager is bound to a single request and caps the reply count at the rack count of its datacenter.
Implementations§
Source§impl ResponseMgr
impl ResponseMgr
Sourcepub fn new(req: &Msg, max_responses: u8, dc_name: Option<String>) -> Self
pub fn new(req: &Msg, max_responses: u8, dc_name: Option<String>) -> Self
Build a manager bound to req that expects at most
max_responses replies.
max_responses must be in the range 1..=MAX_REPLICAS_PER_DC;
the reference engine derives it from the rack count of the
target datacenter and panics on out-of-range values, which the
Rust port surfaces as a debug assertion.
§Examples
use dynomite::msg::{Msg, MsgType, ResponseMgr};
let req = Msg::new(1, MsgType::ReqRedisGet, true);
let mgr = ResponseMgr::new(&req, 3, None);
assert_eq!(mgr.max_responses(), 3);
assert_eq!(mgr.quorum_responses(), 2);Sourcepub fn is_read(&self) -> bool
pub fn is_read(&self) -> bool
True when the manager is bound to a read request.
§Examples
use dynomite::msg::{Msg, MsgType, ResponseMgr};
let req = Msg::new(1, MsgType::ReqRedisGet, true);
assert!(ResponseMgr::new(&req, 1, None).is_read());Sourcepub fn max_responses(&self) -> u8
pub fn max_responses(&self) -> u8
Highest response count this manager will ever accept.
Sourcepub fn quorum_responses(&self) -> u8
pub fn quorum_responses(&self) -> u8
Number of good responses required before quorum can be declared.
Sourcepub fn good_responses(&self) -> u8
pub fn good_responses(&self) -> u8
Number of accepted (non-error) responses received so far.
Sourcepub fn error_responses(&self) -> u8
pub fn error_responses(&self) -> u8
Number of error responses received so far.
Sourcepub fn pending_responses(&self) -> u8
pub fn pending_responses(&self) -> u8
Number of replies still expected before any decision.
Sourcepub fn submit_response(&mut self, rsp: Msg, checksum: u32)
pub fn submit_response(&mut self, rsp: Msg, checksum: u32)
Submit rsp paired with its body checksum checksum.
Errors are tallied separately; the first error response is
retained as the canonical error to propagate when no quorum
is possible. Good responses past MAX_REPLICAS_PER_DC are
dropped to mirror the fixed-size array in the reference
engine.
§Examples
use dynomite::msg::{Msg, MsgType, ResponseMgr};
let req = Msg::new(1, MsgType::ReqRedisGet, true);
let mut mgr = ResponseMgr::new(&req, 1, None);
let rsp = Msg::new(2, MsgType::RspRedisStatus, false);
mgr.submit_response(rsp, 0xdead_beef);
assert_eq!(mgr.good_responses(), 1);Sourcepub fn outcome(&self) -> QuorumOutcome
pub fn outcome(&self) -> QuorumOutcome
Determine whether the manager has reached a final decision
and, if so, what kind. Mirrors rspmgr_check_is_done plus
rspmgr_is_quorum_achieved.
§Examples
use dynomite::msg::{
Msg, MsgType, QuorumOutcome, ResponseMgr,
};
let req = Msg::new(1, MsgType::ReqRedisGet, true);
let mut mgr = ResponseMgr::new(&req, 1, None);
assert_eq!(mgr.outcome(), QuorumOutcome::Pending);
mgr.submit_response(Msg::new(2, MsgType::RspRedisStatus, false), 1);
assert_eq!(mgr.outcome(), QuorumOutcome::Achieved);Sourcepub fn is_done(&self) -> bool
pub fn is_done(&self) -> bool
Convenience: true when outcome reports anything but
QuorumOutcome::Pending.
§Examples
use dynomite::msg::{Msg, MsgType, ResponseMgr};
let req = Msg::new(1, MsgType::ReqRedisGet, true);
let mgr = ResponseMgr::new(&req, 3, None);
assert!(!mgr.is_done());Sourcepub fn error_response(&self) -> Option<&Msg>
pub fn error_response(&self) -> Option<&Msg>
Borrow the first error response, if any.
§Examples
use dynomite::msg::{Msg, MsgType, ResponseMgr};
let req = Msg::new(1, MsgType::ReqRedisGet, true);
let mgr = ResponseMgr::new(&req, 1, None);
assert!(mgr.error_response().is_none());Sourcepub fn good_iter(&self) -> impl Iterator<Item = (&Msg, u32)>
pub fn good_iter(&self) -> impl Iterator<Item = (&Msg, u32)>
Iterate over the accepted responses paired with their checksums.
Sourcepub fn pick_response(&self) -> Option<&Msg>
pub fn pick_response(&self) -> Option<&Msg>
Pick a response to forward to the client according to the majority-checksum rule.
Returns None when quorum has not been achieved (the caller
should consult Self::outcome and propagate the error
response from Self::error_response).
§Examples
use dynomite::msg::{
Msg, MsgType, QuorumOutcome, ResponseMgr,
};
let req = Msg::new(1, MsgType::ReqRedisGet, true);
let mut mgr = ResponseMgr::new(&req, 3, None);
for id in 2..=4 {
mgr.submit_response(Msg::new(id, MsgType::RspRedisStatus, false), 7);
}
assert_eq!(mgr.outcome(), QuorumOutcome::Achieved);
assert!(mgr.pick_response().is_some());