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());Trait Implementations§
Auto Trait Implementations§
impl Freeze for ResponseMgr
impl RefUnwindSafe for ResponseMgr
impl Send for ResponseMgr
impl Sync for ResponseMgr
impl Unpin for ResponseMgr
impl UnsafeUnpin for ResponseMgr
impl UnwindSafe for ResponseMgr
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> FutureExt for T
impl<T> FutureExt for T
Source§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
Source§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.