use std::sync::Arc; use actix::{ fut::{wrap_future, ActorFuture}, Actor, Addr, AsyncContext, Context, Handler, Message, }; use background_jobs_core::{JobInfo, ProcessorMap}; use log::info; use crate::{EitherJob, RequestJob, Server}; pub struct ProcessJob { job: JobInfo, } impl ProcessJob { pub fn new(job: JobInfo) -> Self { ProcessJob { job } } } impl Message for ProcessJob { type Result = (); } pub struct LocalWorker where State: Clone + 'static, { id: usize, queue: String, processors: Arc>, server: Addr>>, } impl LocalWorker where State: Clone + 'static, { pub fn new( id: usize, queue: String, processors: Arc>, server: Addr>, ) -> Self { LocalWorker { id, queue, processors, server, } } } impl Actor for LocalWorker where State: Clone + 'static, { type Context = Context; fn started(&mut self, ctx: &mut Self::Context) { self.server .do_send(RequestJob::new(self.id, &self.queue, ctx.address())); } } impl Handler for LocalWorker where State: Clone + 'static, { type Result = (); fn handle(&mut self, msg: ProcessJob, ctx: &mut Self::Context) -> Self::Result { info!("Worker {} processing job {}", self.id, msg.job.id()); let fut = wrap_future::<_, Self>(self.processors.process_job(msg.job)).map(|job, actor, ctx| { actor.server.do_send(EitherJob::Existing(job)); actor .server .do_send(RequestJob::new(actor.id, &actor.queue, ctx.address())); }); ctx.spawn(fut); } }