use crate::core::types::MsgId;
use super::message::Msg;
use super::queue::MsgQueue;
pub fn set_error(req: &mut Msg, error_code: i32, dyn_error_code: super::DynErrorCode) -> bool {
if req.flags().is_error {
return false;
}
req.set_is_error(true);
req.flags_mut().done = true;
req.set_error_code(error_code);
req.set_dyn_error_code(dyn_error_code);
true
}
#[must_use]
pub fn is_done(req: &Msg) -> bool {
if req.selected_rsp().is_none() {
return false;
}
if req.fragment_ids().is_empty() {
return true;
}
req.flags().fdone
}
#[must_use]
pub fn is_error(req: &Msg) -> bool {
req.flags().is_error || req.flags().is_ferror
}
pub fn move_completed(from: &mut MsgQueue, to: &mut MsgQueue, id: MsgId) {
let mut keep = MsgQueue::new();
while let Some(msg) = from.pop_front() {
if msg.selected_rsp() == Some(id) {
to.push_back(msg);
} else {
keep.push_back(msg);
}
}
while let Some(msg) = keep.pop_front() {
from.push_back(msg);
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::msg::{DynErrorCode, MsgType};
#[test]
fn error_flags_propagate() {
let mut req = Msg::new(1, MsgType::ReqRedisGet, true);
assert!(set_error(&mut req, 7, DynErrorCode::PeerHostDown));
assert!(req.flags().is_error);
assert!(req.flags().done);
assert_eq!(req.error_code(), 7);
assert_eq!(req.dyn_error_code(), DynErrorCode::PeerHostDown);
assert!(is_error(&req));
assert!(!set_error(&mut req, 9, DynErrorCode::DynomiteUnknownError));
assert_eq!(req.error_code(), 7);
}
#[test]
fn fragmented_request_done_requires_fdone() {
let mut req = Msg::new(1, MsgType::ReqRedisMget, true);
req.push_fragment_id(2);
req.set_selected_rsp(Some(99));
assert!(!is_done(&req));
req.flags_mut().fdone = true;
assert!(is_done(&req));
}
#[test]
fn is_done_false_without_selected_rsp() {
let req = Msg::new(1, MsgType::ReqRedisGet, true);
assert!(req.selected_rsp().is_none());
assert!(!is_done(&req));
}
#[test]
fn is_done_true_for_non_fragmented_with_response() {
let mut req = Msg::new(1, MsgType::ReqRedisGet, true);
req.set_selected_rsp(Some(2));
assert!(req.fragment_ids().is_empty());
assert!(is_done(&req));
}
#[test]
fn move_completed_partitions_by_selected_rsp() {
use crate::msg::MsgQueue;
let mut from = MsgQueue::new();
let mut to = MsgQueue::new();
for (id, rsp) in [(1u64, 99u64), (2, 7), (3, 99)] {
let mut m = Msg::new(id, MsgType::ReqRedisGet, true);
m.set_selected_rsp(Some(rsp));
from.push_back(m);
}
move_completed(&mut from, &mut to, 99);
assert_eq!(to.len(), 2);
assert_eq!(from.len(), 1);
assert_eq!(from.front().unwrap().id(), 2);
}
}