use messaging_thread_pool::*;
use messaging_thread_pool_macros::pool_item;
use std::cell::RefCell;
use std::rc::Rc;
#[derive(Debug, Clone)]
struct HistoryTracker {
log: Rc<RefCell<Vec<String>>>,
}
impl HistoryTracker {
fn add_entry(&self, entry: String) {
self.log.borrow_mut().push(entry);
}
}
#[derive(Debug)]
pub struct UserSession {
id: u64,
log: Rc<RefCell<Vec<String>>>,
tracker: HistoryTracker,
}
impl IdTargeted for UserSession {
fn id(&self) -> u64 {
self.id
}
}
#[pool_item]
impl UserSession {
pub fn new(id: u64) -> Self {
let log = Rc::new(RefCell::new(Vec::new()));
let tracker = HistoryTracker { log: log.clone() };
Self { id, log, tracker }
}
#[messaging(LogActionRequest, LogActionResponse)]
pub fn log_action(&self, action: String) -> usize {
self.tracker.add_entry(format!("Action: {}", action));
self.log.borrow().len()
}
#[messaging(GetLogRequest, GetLogResponse)]
pub fn get_log(&self) -> Vec<String> {
self.log.borrow().clone()
}
}
#[test]
pub fn example_rc_state_management() {
let thread_pool = ThreadPool::<UserSession>::new(2);
thread_pool
.send_and_receive(vec![UserSessionInit(1)].into_iter())
.expect("session creation")
.for_each(|_| {});
let counts: Vec<usize> = thread_pool
.send_and_receive(
vec![
LogActionRequest(1, "Login".to_string()),
LogActionRequest(1, "ViewProfile".to_string()),
LogActionRequest(1, "Logout".to_string()),
]
.into_iter(),
)
.expect("actions")
.map(|resp| resp.result)
.collect();
assert_eq!(counts, vec![1, 2, 3]);
let log = thread_pool
.send_and_receive(vec![GetLogRequest(1)].into_iter())
.expect("get log")
.next()
.unwrap()
.result;
assert_eq!(log[0], "Action: Login");
assert_eq!(log[1], "Action: ViewProfile");
assert_eq!(log[2], "Action: Logout");
}