remove rocket dependencies for manager notifications
This commit is contained in:
+25
-31
@@ -2,13 +2,10 @@ use std::collections::VecDeque;
|
||||
use std::sync::{mpsc::Receiver, Arc, Condvar, Mutex};
|
||||
use std::{thread, time};
|
||||
|
||||
use rocket::{response::stream::EventStream, Shutdown};
|
||||
|
||||
use super::handler::Handler;
|
||||
use crate::error::HandlerError;
|
||||
use crate::message::{Message, Subject};
|
||||
use crate::model::*;
|
||||
use crate::notification::Notification;
|
||||
|
||||
// Queue is a simple queue data structure.
|
||||
//
|
||||
@@ -35,22 +32,22 @@ pub enum WorkerStatus {
|
||||
Stopped,
|
||||
}
|
||||
|
||||
struct Worker<T> {
|
||||
struct Worker<H, N> {
|
||||
id: u32,
|
||||
manager: String,
|
||||
queue: Arc<Queue<Message>>,
|
||||
status: Arc<Mutex<WorkerStatus>>,
|
||||
shared_handler: Arc<T>,
|
||||
notifier: Arc<Notification<Message>>,
|
||||
shared_handler: Arc<H>,
|
||||
notifier: Arc<N>,
|
||||
}
|
||||
|
||||
impl<T: Handler> Worker<T> {
|
||||
impl<H: Handler, N: Notifier> Worker<H, N> {
|
||||
fn new(
|
||||
id: u32,
|
||||
manager: String,
|
||||
queue: Arc<Queue<Message>>,
|
||||
shared_handler: Arc<T>,
|
||||
notifier: Arc<Notification<Message>>,
|
||||
shared_handler: Arc<H>,
|
||||
notifier: Arc<N>,
|
||||
) -> Self {
|
||||
Self {
|
||||
id: id,
|
||||
@@ -75,7 +72,7 @@ impl<T: Handler> Worker<T> {
|
||||
//
|
||||
// It tries to parse the incoming `Message` into a `Runner` and runs it.
|
||||
// If an `Unknown` error is returned from the handler, the thread is stopped and its status is set to `Failed`.
|
||||
fn launch<U: Runner>(&self) {
|
||||
fn launch<R: Runner>(&self) {
|
||||
let queue = self.queue.clone();
|
||||
let status = self.status.clone();
|
||||
let handler = self.shared_handler.clone();
|
||||
@@ -93,13 +90,13 @@ impl<T: Handler> Worker<T> {
|
||||
};
|
||||
|
||||
if message.get_subject() == Subject::StopManager {
|
||||
Worker::<T>::set_status(&status, WorkerStatus::Stopped);
|
||||
Worker::<H, N>::set_status(&status, WorkerStatus::Stopped);
|
||||
break;
|
||||
}
|
||||
|
||||
drop(guard);
|
||||
|
||||
let mut runner = match U::try_from(message) {
|
||||
let mut runner = match R::try_from(message) {
|
||||
Ok(r) => r,
|
||||
Err(_e) => {
|
||||
eprintln!("unable to parse the incoming message into a runner");
|
||||
@@ -107,23 +104,21 @@ impl<T: Handler> Worker<T> {
|
||||
}
|
||||
};
|
||||
|
||||
Worker::<T>::set_status(&status, WorkerStatus::Running);
|
||||
Worker::<H, N>::set_status(&status, WorkerStatus::Running);
|
||||
|
||||
// TODO: the message could be requeued if needed
|
||||
if let Err(e) = handler.handle(runner.run()) {
|
||||
match e {
|
||||
HandlerError::Unknown => {
|
||||
Worker::<T>::set_status(&status, WorkerStatus::Failed);
|
||||
Worker::<H, N>::set_status(&status, WorkerStatus::Failed);
|
||||
break;
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
// TODO: collect a message from the handler (modify the signature)
|
||||
// TODO: unwrap() on send is useless since it can failed
|
||||
let guard = notifier.get_sender();
|
||||
guard.send(Message::empty()).unwrap();
|
||||
Worker::<T>::set_status(&status, WorkerStatus::Pending);
|
||||
notifier.send(Message::empty());
|
||||
Worker::<H, N>::set_status(&status, WorkerStatus::Pending);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -141,18 +136,17 @@ pub enum ManagerStatus {
|
||||
}
|
||||
|
||||
// Manager is a pool of workers and holds a queue containing `Message`.
|
||||
pub struct Manager<T> {
|
||||
pub struct Manager<H, N> {
|
||||
name: String,
|
||||
status: ManagerStatus,
|
||||
workers: Vec<Worker<T>>,
|
||||
workers: Vec<Worker<H, N>>,
|
||||
queue: Arc<Queue<Message>>,
|
||||
shared_handler: Arc<T>,
|
||||
notifier: Arc<Notification<Message>>,
|
||||
shared_handler: Arc<H>,
|
||||
notifier: Arc<N>,
|
||||
}
|
||||
|
||||
impl<T: Handler> Manager<T> {
|
||||
pub fn new(name: &str, shared_handler: T) -> Self {
|
||||
let notifier = Arc::new(Notification::<Message>::init());
|
||||
impl<H: Handler, N: Notifier> Manager<H, N> {
|
||||
pub fn new(name: &str, shared_handler: H, notifier: Arc<N>) -> Self {
|
||||
Self {
|
||||
name: name.to_string(),
|
||||
workers: vec![],
|
||||
@@ -171,25 +165,25 @@ impl<T: Handler> Manager<T> {
|
||||
//
|
||||
// Example:
|
||||
// deployer.launch_workers::<Job>(5)
|
||||
pub fn launch_workers<U: Runner>(&mut self, nb_workers: u32) {
|
||||
pub fn launch_workers<R: Runner>(&mut self, nb_workers: u32) {
|
||||
for i in 0..nb_workers {
|
||||
let worker: Worker<T> = Worker::new(
|
||||
let worker: Worker<H, N> = Worker::new(
|
||||
i,
|
||||
self.name.clone(),
|
||||
self.queue.clone(),
|
||||
self.shared_handler.clone(),
|
||||
self.notifier.clone(),
|
||||
);
|
||||
worker.launch::<U>();
|
||||
worker.launch::<R>();
|
||||
self.workers.push(worker);
|
||||
}
|
||||
|
||||
self.status = ManagerStatus::Up;
|
||||
}
|
||||
|
||||
pub async fn get_events(&self, end: Shutdown) -> EventStream![] {
|
||||
self.notifier.events(end).await
|
||||
}
|
||||
// pub async fn get_events(&self, end: Shutdown) -> EventStream![] {
|
||||
// self.notifier.events(end).await
|
||||
// }
|
||||
|
||||
// subscribe subscribes to a `Receiver` channel and notify all the related workers.
|
||||
pub fn subscribe(&self, receiver: Receiver<Message>) {
|
||||
|
||||
Reference in New Issue
Block a user