use std::sync::Arc; use actix::{Actor, Context, Handler, Message}; use emgauwa_lib::errors::EmgauwaError; use emgauwa_lib::models::Controller; use futures::executor::block_on; use sqlx::{Pool, Sqlite}; use tokio::sync::Notify; #[derive(Message)] #[rtype(result = "Result<(), EmgauwaError>")] pub struct Reload {} #[derive(Message)] #[rtype(result = "Controller")] pub struct GetThis {} #[derive(Message)] #[rtype(result = "Arc")] pub struct GetNotifier {} pub struct AppState { pub pool: Pool, pub this: Controller, pub notifier: Arc, } impl AppState { pub fn new(pool: Pool, this: Controller) -> AppState { AppState { pool, this, notifier: Arc::new(Notify::new()), } } pub fn notify_change(&self) { self.notifier.notify_one(); } } impl Actor for AppState { type Context = Context; } impl Handler for AppState { type Result = Result<(), EmgauwaError>; fn handle(&mut self, _msg: Reload, _ctx: &mut Self::Context) -> Self::Result { log::debug!("Reloading controller"); let mut pool_conn = block_on(self.pool.acquire())?; self.this.reload(&mut pool_conn)?; self.notify_change(); Ok(()) } } impl Handler for AppState { type Result = Controller; fn handle(&mut self, _msg: GetThis, _ctx: &mut Self::Context) -> Self::Result { self.this.clone() } } impl Handler for AppState { type Result = Arc; fn handle(&mut self, _msg: GetNotifier, _ctx: &mut Self::Context) -> Self::Result { Arc::clone(&self.notifier) } }