use std::sync::{Arc, Mutex};
use crate::concurrent::agent_runner::Agent;
use crate::concurrent::logbuffer::term_reader::ErrorHandler;
pub struct AgentInvoker<T: Agent> {
agent: Arc<Mutex<T>>,
exception_handler: Box<dyn ErrorHandler>,
is_started: bool,
is_running: bool,
is_closed: bool,
}
impl<T: Agent> AgentInvoker<T> {
pub fn new(agent: Arc<Mutex<T>>, exception_handler: Box<dyn ErrorHandler>) -> Self {
Self {
agent,
exception_handler,
is_started: false,
is_running: false,
is_closed: false,
}
}
pub fn is_started(&self) -> bool {
self.is_started
}
pub fn is_running(&self) -> bool {
self.is_running
}
pub fn is_closed(&self) -> bool {
self.is_closed
}
pub fn start(&mut self) {
if !self.is_started {
self.is_started = true;
let on_start_result = self.agent.lock().expect("Mutex poisoned").on_start();
if let Err(error) = on_start_result {
self.exception_handler.call(error);
self.close();
} else {
self.is_running = true;
}
}
}
pub fn invoke(&self) -> i32 {
let mut work_count = 0;
if self.is_running {
match self.agent.lock().expect("Mutex poisoned").do_work() {
Err(error) => self.exception_handler.call(error),
Ok(wrk_cnt) => work_count = wrk_cnt,
}
}
work_count
}
pub fn close(&mut self) {
if !self.is_closed {
self.is_running = false;
self.is_closed = true;
if let Err(error) = self.agent.lock().expect("Mutex poisoned").on_close() {
self.exception_handler.call(error);
}
}
}
}