background-jobs/jobs-actix/src/worker.rs

123 lines
3.1 KiB
Rust
Raw Normal View History

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,
};
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
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
{
id: u64,
2018-12-16 18:43:44 +00:00
queue: String,
processors: CachedProcessorMap<State>,
2019-05-27 17:29:11 +00:00
server: Addr<S>,
2018-12-16 18:43:44 +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
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,
}
}
}
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 = ();
}
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| {
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);
}
}