summer-apalis 0.7.1

Integration of rust application framework summer-rs and apalis
Documentation
use apalis::prelude::Monitor;
use summer::{
    app::AppBuilder,
    async_trait,
    error::Result,
    plugin::{component::ComponentRef, ComponentRegistry, MutableComponentRegistry, Plugin},
    signal,
};

pub use apalis;
#[cfg(feature = "amqp")]
pub use apalis_amqp;
#[cfg(feature = "board")]
pub use apalis_board;
#[cfg(feature = "sql-mysql")]
pub use apalis_mysql;
#[cfg(feature = "sql-postgres")]
pub use apalis_postgres;
#[cfg(feature = "redis")]
pub use apalis_redis;
#[cfg(feature = "sql-sqlite")]
pub use apalis_sqlite;
#[cfg(any(feature = "sql-postgres", feature = "sql-sqlite", feature = "sql-mysql"))]
pub use summer_sqlx;

pub struct ApalisPlugin;

pub type WorkerRegister = fn(&mut AppBuilder, Monitor) -> Monitor;

#[async_trait]
impl Plugin for ApalisPlugin {
    async fn build(&self, app: &mut AppBuilder) {
        if let Some(builders) = app.get_component::<Vec<WorkerRegister>>() {
            let mut monitor = Monitor::new();
            for build_fn in &builders {
                monitor = build_fn(app, monitor);
            }
            if !builders.is_empty() {
                app.add_scheduler(move |_app| Box::new(Self::schedule(monitor)));
            }
        }
    }

    #[cfg(feature = "redis")]
    fn dependencies(&self) -> Vec<&str> {
        vec![std::any::type_name::<summer_redis::RedisPlugin>()]
    }

    #[cfg(all(
        any(feature = "sql-postgres", feature = "sql-sqlite", feature = "sql-mysql"),
        not(feature = "redis")
    ))]
    fn dependencies(&self) -> Vec<&str> {
        vec![std::any::type_name::<summer_sqlx::SqlxPlugin>()]
    }
}

impl ApalisPlugin {
    async fn schedule(monitor: Monitor) -> Result<String> {
        let _ = monitor.run_with_signal(shutdown_signal()).await;
        Ok("apalis scheduled finished".to_string())
    }
}

async fn shutdown_signal() -> std::io::Result<()> {
    let _ = signal::shutdown_signal("apalis").await;
    Ok(())
}

pub trait ApalisConfigurator {
    fn add_worker(&mut self, worker_register: WorkerRegister) -> &mut Self;
}

impl ApalisConfigurator for AppBuilder {
    fn add_worker(&mut self, worker_register: WorkerRegister) -> &mut Self {
        if let Some(workers) = self.get_component_ref::<Vec<WorkerRegister>>() {
            unsafe {
                let raw_ptr = ComponentRef::into_raw(workers);
                let workers = &mut *(raw_ptr as *mut Vec<WorkerRegister>);
                workers.push(worker_register);
            }
            self
        } else {
            self.add_component(vec![worker_register])
        }
    }
}