2018-12-16 18:43:44 +00:00
|
|
|
use actix::{
|
2019-05-27 17:29:11 +00:00
|
|
|
dev::ToEnvelope,
|
2018-12-16 18:43:44 +00:00
|
|
|
fut::{wrap_future, ActorFuture},
|
|
|
|
Actor, Addr, AsyncContext, Context, Handler, Message,
|
|
|
|
};
|
2019-10-31 18:46:41 +00:00
|
|
|
use background_jobs_core::{JobInfo, CachedProcessorMap};
|
2018-12-16 18:43:44 +00:00
|
|
|
use log::info;
|
|
|
|
|
2019-05-27 17:29:11 +00:00
|
|
|
use crate::{RequestJob, ReturningJob};
|
2018-12-16 18:43:44 +00:00
|
|
|
|
2019-05-27 17:29:11 +00:00
|
|
|
pub trait Worker {
|
|
|
|
fn process_job(&self, job: JobInfo);
|
|
|
|
|
|
|
|
fn id(&self) -> u64;
|
|
|
|
|
|
|
|
fn queue(&self) -> &str;
|
2018-12-16 18:43:44 +00:00
|
|
|
}
|
|
|
|
|
2019-05-27 17:29:11 +00:00
|
|
|
pub struct LocalWorkerHandle<W>
|
|
|
|
where
|
|
|
|
W: Actor + Handler<ProcessJob>,
|
|
|
|
W::Context: ToEnvelope<W, ProcessJob>,
|
|
|
|
{
|
|
|
|
addr: Addr<W>,
|
|
|
|
id: u64,
|
|
|
|
queue: String,
|
2018-12-16 18:43:44 +00:00
|
|
|
}
|
|
|
|
|
2019-05-27 17:29:11 +00:00
|
|
|
impl<W> Worker for LocalWorkerHandle<W>
|
|
|
|
where
|
|
|
|
W: Actor + Handler<ProcessJob>,
|
|
|
|
W::Context: ToEnvelope<W, ProcessJob>,
|
|
|
|
{
|
|
|
|
fn process_job(&self, job: JobInfo) {
|
|
|
|
self.addr.do_send(ProcessJob(job));
|
|
|
|
}
|
|
|
|
|
|
|
|
fn id(&self) -> u64 {
|
|
|
|
self.id
|
|
|
|
}
|
|
|
|
|
|
|
|
fn queue(&self) -> &str {
|
|
|
|
&self.queue
|
|
|
|
}
|
2018-12-16 18:43:44 +00:00
|
|
|
}
|
|
|
|
|
2019-09-22 17:33:33 +00:00
|
|
|
/// A worker that runs on the same system as the jobs server
|
2019-05-25 20:22:26 +00:00
|
|
|
pub struct LocalWorker<S, State>
|
2018-12-16 18:43:44 +00:00
|
|
|
where
|
2019-05-27 17:29:11 +00:00
|
|
|
S: Actor + Handler<ReturningJob> + Handler<RequestJob>,
|
|
|
|
S::Context: ToEnvelope<S, ReturningJob> + ToEnvelope<S, RequestJob>,
|
2019-05-24 03:41:34 +00:00
|
|
|
State: Clone + 'static,
|
2018-12-16 18:43:44 +00:00
|
|
|
{
|
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>,
|
2019-05-27 17:29:11 +00:00
|
|
|
server: Addr<S>,
|
2018-12-16 18:43:44 +00:00
|
|
|
}
|
|
|
|
|
2019-05-25 20:22:26 +00:00
|
|
|
impl<S, State> LocalWorker<S, State>
|
2018-12-16 18:43:44 +00:00
|
|
|
where
|
2019-05-27 17:29:11 +00:00
|
|
|
S: Actor + Handler<ReturningJob> + Handler<RequestJob>,
|
|
|
|
S::Context: ToEnvelope<S, ReturningJob> + ToEnvelope<S, RequestJob>,
|
2019-05-24 03:41:34 +00:00
|
|
|
State: Clone + 'static,
|
2018-12-16 18:43:44 +00:00
|
|
|
{
|
2019-09-22 17:33:33 +00:00
|
|
|
/// Create a new local worker
|
2019-10-31 18:46:41 +00:00
|
|
|
pub fn new(id: u64, queue: String, processors: CachedProcessorMap<State>, server: Addr<S>) -> Self {
|
2018-12-16 18:43:44 +00:00
|
|
|
LocalWorker {
|
|
|
|
id,
|
|
|
|
queue,
|
|
|
|
processors,
|
|
|
|
server,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-25 20:22:26 +00:00
|
|
|
impl<S, State> Actor for LocalWorker<S, State>
|
2018-12-16 18:43:44 +00:00
|
|
|
where
|
2019-05-27 17:29:11 +00:00
|
|
|
S: Actor + Handler<ReturningJob> + Handler<RequestJob>,
|
|
|
|
S::Context: ToEnvelope<S, ReturningJob> + ToEnvelope<S, RequestJob>,
|
2019-05-24 03:41:34 +00:00
|
|
|
State: Clone + 'static,
|
2018-12-16 18:43:44 +00:00
|
|
|
{
|
|
|
|
type Context = Context<Self>;
|
|
|
|
|
|
|
|
fn started(&mut self, ctx: &mut Self::Context) {
|
2019-05-27 17:29:11 +00:00
|
|
|
self.server.do_send(RequestJob(Box::new(LocalWorkerHandle {
|
|
|
|
id: self.id,
|
|
|
|
queue: self.queue.clone(),
|
|
|
|
addr: ctx.address(),
|
|
|
|
})));
|
2018-12-16 18:43:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-27 17:29:11 +00:00
|
|
|
pub struct ProcessJob(JobInfo);
|
|
|
|
|
|
|
|
impl Message for ProcessJob {
|
|
|
|
type Result = ();
|
|
|
|
}
|
|
|
|
|
2019-05-25 20:22:26 +00:00
|
|
|
impl<S, State> Handler<ProcessJob> for LocalWorker<S, State>
|
2018-12-16 18:43:44 +00:00
|
|
|
where
|
2019-05-27 17:29:11 +00:00
|
|
|
S: Actor + Handler<ReturningJob> + Handler<RequestJob>,
|
|
|
|
S::Context: ToEnvelope<S, ReturningJob> + ToEnvelope<S, RequestJob>,
|
2019-05-24 03:41:34 +00:00
|
|
|
State: Clone + 'static,
|
2018-12-16 18:43:44 +00:00
|
|
|
{
|
|
|
|
type Result = ();
|
|
|
|
|
2019-05-27 17:29:11 +00:00
|
|
|
fn handle(&mut self, ProcessJob(job): ProcessJob, ctx: &mut Self::Context) -> Self::Result {
|
|
|
|
info!("Worker {} processing job {}", self.id, job.id());
|
2018-12-16 18:43:44 +00:00
|
|
|
let fut =
|
2019-05-27 17:29:11 +00:00
|
|
|
wrap_future::<_, Self>(self.processors.process_job(job)).map(|job, actor, ctx| {
|
2019-05-25 20:22:26 +00:00
|
|
|
actor.server.do_send(ReturningJob(job));
|
2019-05-27 17:29:11 +00:00
|
|
|
actor.server.do_send(RequestJob(Box::new(LocalWorkerHandle {
|
|
|
|
id: actor.id,
|
|
|
|
queue: actor.queue.clone(),
|
|
|
|
addr: ctx.address(),
|
|
|
|
})));
|
2018-12-16 18:43:44 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
ctx.spawn(fut);
|
|
|
|
}
|
|
|
|
}
|