replace job->message in queue
This commit is contained in:
+22
-21
@@ -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
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user