replace job->message in queue

This commit is contained in:
rmanach
2023-04-19 11:30:12 +02:00
parent 452cfc81b9
commit d5b3affe5d
9 changed files with 170 additions and 96 deletions
+22 -21
View File
@@ -1,11 +1,11 @@
use std::sync::mpsc::Sender;
use std::sync::{Arc, Mutex};
use std::marker::{Send, Sync};
use std::sync::{mpsc::Sender, Arc, Mutex};
use crate::error::{HandlerError, RunnerError};
use crate::message::Message;
use crate::model::{Job, JobAction};
use crate::message::{Message, Subject};
use crate::model::JobAction;
pub trait Handler {
pub trait Handler: Sync + Send + 'static {
fn handle(&self, res: Result<Message, RunnerError>) -> Result<(), HandlerError>;
}
@@ -17,9 +17,9 @@ impl CheckHandler {
}
fn manage_message(&self, message: Message) -> Result<(), HandlerError> {
match message {
Message::CheckDeploy(_body) => Ok(()),
Message::StopManager => Err(HandlerError::Unknown),
match message.get_subject() {
Subject::Action(_) | Subject::Empty => Ok(()),
Subject::StopManager => Err(HandlerError::Unknown),
}
}
}
@@ -34,27 +34,28 @@ impl Handler for CheckHandler {
}
pub struct DeployHandler {
sender: Arc<Mutex<Sender<Job>>>,
sender: Arc<Mutex<Sender<Message>>>,
}
impl DeployHandler {
pub fn new(sender: Arc<Mutex<Sender<Job>>>) -> Self {
pub fn new(sender: Arc<Mutex<Sender<Message>>>) -> Self {
Self { sender }
}
fn manage_message(&self, message: Message) -> Result<(), HandlerError> {
match message {
Message::CheckDeploy(body) => {
let guard = self.sender.lock().unwrap();
let id: i32 = body.get_id().try_into().unwrap();
if let Err(e) = guard.send(Job::new(id, JobAction::MegaportCheckDeploy)) {
println!("[handler(deploy)] error: {}", e);
match message.get_subject() {
Subject::Action(action) => match action {
JobAction::Check => {
let guard = self.sender.lock().unwrap();
if let Err(e) = guard.send(message) {
println!("[handler(deploy)] error: {}", e);
}
Ok(())
}
Ok(())
}
Message::StopManager => Err(HandlerError::Unknown),
JobAction::Deploy => Ok(()),
},
Subject::StopManager => Err(HandlerError::Unknown),
Subject::Empty => Ok(()),
}
}
}
+23 -17
View File
@@ -1,10 +1,10 @@
use std::collections::VecDeque;
use std::marker::{Send, Sync};
use std::sync::{mpsc::Receiver, Arc, Condvar, Mutex};
use std::thread;
use super::handler::Handler;
use crate::error::HandlerError;
use crate::message::Message;
use crate::model::*;
// Queue is a simple queue data structure.
@@ -60,24 +60,22 @@ impl Worker {
}
// Manager is a pool of workers and holds a queue containing `Job` to run.
//
// TODO: to handle more message, replace the trait with a `Message` trait.
pub struct Manager<T: Runner> {
pub struct Manager {
name: String,
workers: Vec<Arc<Mutex<Worker>>>,
queue: Arc<Queue<T>>,
queue: Arc<Queue<Message>>,
}
impl<T: Runner + Send + 'static> Manager<T> {
impl Manager {
pub fn new(name: &str) -> Self {
Self {
name: name.to_string(),
workers: vec![],
queue: Arc::new(Queue::<T>::new()),
queue: Arc::new(Queue::new()),
}
}
pub fn launch_workers<U: Handler + Sync + Send + 'static>(
pub fn launch_workers<T: Runner, U: Handler>(
&mut self,
nb_workers: u32,
shared_handler: Arc<U>,
@@ -93,9 +91,9 @@ impl<T: Runner + Send + 'static> Manager<T> {
thread::spawn(move || loop {
let mut guard = queue.content.lock().unwrap();
let mut runner = loop {
if let Some(r) = guard.pop_front() {
break r;
let message = loop {
if let Some(m) = guard.pop_front() {
break m;
} else {
guard = queue.not_empty.wait(guard).unwrap();
}
@@ -103,23 +101,31 @@ impl<T: Runner + Send + 'static> Manager<T> {
drop(guard);
Manager::<T>::set_worker_status(&worker, WorkerStatus::Running);
let mut runner = match T::try_from(message) {
Ok(r) => r,
Err(_e) => {
eprintln!("unable to parse the incoming message into a runner");
continue;
}
};
Manager::set_worker_status(&worker, WorkerStatus::Running);
if let Err(e) = handler.handle(runner.run()) {
match e {
HandlerError::Unknown => {
Manager::<T>::set_worker_status(&worker, WorkerStatus::Failed);
Manager::set_worker_status(&worker, WorkerStatus::Failed);
break;
}
_ => (),
}
}
Manager::<T>::set_worker_status(&worker, WorkerStatus::Pending);
Manager::set_worker_status(&worker, WorkerStatus::Pending);
});
}
}
// subscribe subscribes to a `Receiver` channel.
pub fn subscribe(&self, receiver: Receiver<T>) {
pub fn subscribe(&self, receiver: Receiver<Message>) {
let queue = self.queue.clone();
thread::spawn(move || loop {
match receiver.recv() {
@@ -138,9 +144,9 @@ impl<T: Runner + Send + 'static> Manager<T> {
});
}
pub fn add_runner(&self, runner: T) {
pub fn put_message(&self, message: Message) {
let mut q = self.queue.content.lock().unwrap();
q.push_back(runner);
q.push_back(message);
self.queue.not_empty.notify_one();
}