2020-03-21 02:31:03 +00:00
|
|
|
use crate::Server;
|
|
|
|
use background_jobs_core::{CachedProcessorMap, JobInfo};
|
|
|
|
use log::{debug, error, warn};
|
|
|
|
use tokio::sync::mpsc::{channel, Sender};
|
2018-12-16 18:43:44 +00:00
|
|
|
|
2020-03-21 02:31:03 +00:00
|
|
|
#[async_trait::async_trait]
|
2019-05-27 17:29:11 +00:00
|
|
|
pub trait Worker {
|
2020-03-21 02:31:03 +00:00
|
|
|
async fn process_job(&self, job: JobInfo) -> Result<(), JobInfo>;
|
2019-05-27 17:29:11 +00:00
|
|
|
|
|
|
|
fn id(&self) -> u64;
|
|
|
|
|
|
|
|
fn queue(&self) -> &str;
|
2018-12-16 18:43:44 +00:00
|
|
|
}
|
|
|
|
|
2020-03-21 02:31:03 +00:00
|
|
|
#[derive(Clone)]
|
|
|
|
pub(crate) struct LocalWorkerHandle {
|
|
|
|
tx: Sender<JobInfo>,
|
2019-05-27 17:29:11 +00:00
|
|
|
id: u64,
|
|
|
|
queue: String,
|
2018-12-16 18:43:44 +00:00
|
|
|
}
|
|
|
|
|
2020-03-21 02:31:03 +00:00
|
|
|
#[async_trait::async_trait]
|
|
|
|
impl Worker for LocalWorkerHandle {
|
|
|
|
async fn process_job(&self, job: JobInfo) -> Result<(), JobInfo> {
|
|
|
|
match self.tx.clone().send(job).await {
|
|
|
|
Err(e) => {
|
|
|
|
error!("Unable to send job");
|
|
|
|
Err(e.0)
|
|
|
|
}
|
|
|
|
_ => Ok(()),
|
|
|
|
}
|
2019-05-27 17:29:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn id(&self) -> u64 {
|
|
|
|
self.id
|
|
|
|
}
|
|
|
|
|
|
|
|
fn queue(&self) -> &str {
|
|
|
|
&self.queue
|
|
|
|
}
|
2018-12-16 18:43:44 +00:00
|
|
|
}
|
|
|
|
|
2020-03-21 02:31:03 +00:00
|
|
|
pub(crate) fn local_worker<State>(
|
2019-05-25 20:22:26 +00:00
|
|
|
id: u64,
|
2018-12-16 18:43:44 +00:00
|
|
|
queue: String,
|
2019-10-31 18:46:41 +00:00
|
|
|
processors: CachedProcessorMap<State>,
|
2020-03-21 02:31:03 +00:00
|
|
|
server: Server,
|
|
|
|
) where
|
2019-05-24 03:41:34 +00:00
|
|
|
State: Clone + 'static,
|
2018-12-16 18:43:44 +00:00
|
|
|
{
|
2020-03-21 02:31:03 +00:00
|
|
|
let (tx, mut rx) = channel(16);
|
|
|
|
|
|
|
|
let handle = LocalWorkerHandle {
|
|
|
|
tx: tx.clone(),
|
|
|
|
id,
|
|
|
|
queue: queue.clone(),
|
|
|
|
};
|
|
|
|
|
|
|
|
actix::spawn(async move {
|
|
|
|
debug!("Beginning worker loop for {}", id);
|
|
|
|
if let Err(e) = server.request_job(Box::new(handle.clone())).await {
|
|
|
|
error!("Couldn't request first job, bailing, {}", e);
|
|
|
|
return;
|
2018-12-16 18:43:44 +00:00
|
|
|
}
|
2020-03-21 02:31:03 +00:00
|
|
|
while let Some(job) = rx.recv().await {
|
|
|
|
let return_job = processors.process_job(job).await;
|
|
|
|
|
|
|
|
if let Err(e) = server.return_job(return_job).await {
|
|
|
|
error!("Error returning job, {}", e);
|
|
|
|
}
|
|
|
|
if let Err(e) = server.request_job(Box::new(handle.clone())).await {
|
|
|
|
error!("Error requesting job, {}", e);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
warn!("Worker {} closing", id);
|
|
|
|
});
|
2018-12-16 18:43:44 +00:00
|
|
|
}
|