2024-10-04 07:21:10 -04:00
use chrono ::Utc ;
2024-09-22 22:37:47 -04:00
use sqlx ::{ postgres ::PgPoolOptions , Pool , Postgres } ;
2024-10-04 07:21:10 -04:00
use tasks ::import_posts ;
2024-09-21 23:57:37 -04:00
use std ::env ;
2024-10-04 07:21:10 -04:00
use std ::sync ::Arc ;
2024-09-24 20:29:22 -04:00
use std ::time ::Duration ;
2024-09-21 23:57:37 -04:00
2024-09-29 21:15:14 -04:00
//mod config;
2024-09-21 23:57:37 -04:00
mod tasks ;
2024-09-29 21:15:14 -04:00
mod utils ;
2024-09-21 23:57:37 -04:00
2024-09-22 04:10:29 -04:00
pub struct TaskManager < ' a > {
pool : Pool < Postgres > ,
jobs : Vec < TaskJob > ,
2024-09-21 23:57:37 -04:00
last_activated : Option < chrono ::DateTime < Utc > > ,
2024-09-22 04:10:29 -04:00
last_job : Option < TaskJob > ,
scheduler : job_scheduler ::JobScheduler < ' a > ,
2024-09-21 23:57:37 -04:00
}
2024-10-04 07:21:10 -04:00
#[ derive(Debug, sqlx::FromRow) ]
2024-09-21 23:57:37 -04:00
pub struct TaskLog {
2024-10-04 07:21:10 -04:00
log_id : u8 ,
2024-09-21 23:57:37 -04:00
task_id : u8 ,
created_at : chrono ::DateTime < Utc > ,
task_status : TaskStatus ,
2024-10-04 07:21:10 -04:00
finished_at : Option < chrono ::DateTime < Utc > > ,
2024-09-21 23:57:37 -04:00
}
2024-10-04 07:21:10 -04:00
#[ derive(Debug) ]
2024-09-21 23:57:37 -04:00
enum TaskStatus {
2024-10-04 07:21:10 -04:00
Pending ( String ) ,
Completed ( String ) ,
Failed ( String ) ,
2024-09-21 23:57:37 -04:00
}
2024-09-29 21:15:14 -04:00
#[ derive(Debug, sqlx::FromRow, Clone) ]
2024-09-22 04:10:29 -04:00
pub struct TaskJob {
pub task_id : i32 ,
pub task_name : String ,
2024-09-21 23:57:37 -04:00
pub schedule : String ,
2024-09-22 04:10:29 -04:00
pub is_active : bool ,
pub created_at : chrono ::DateTime < Utc > ,
pub deleted_at : Option < chrono ::DateTime < Utc > > ,
2024-09-21 23:57:37 -04:00
}
#[ tokio::main ]
async fn main ( ) {
2024-09-03 01:17:19 -04:00
println! ( " Hello, world! " ) ;
2024-09-22 04:10:29 -04:00
dotenvy ::dotenv ( ) . unwrap ( ) ;
let database_url =
env ::var ( " DATABASE_URL " ) . expect ( " Environment variable DATABASE_URL is not found " ) ;
let pool = PgPoolOptions ::new ( )
. max_connections ( 10 )
2024-09-24 20:29:22 -04:00
. acquire_timeout ( Duration ::from_secs ( 5 ) )
2024-09-22 04:10:29 -04:00
. connect ( & database_url )
. await
. expect ( " Failed to connect to the database " ) ;
let mut manager = TaskManager ::new ( pool ) ;
manager . register_jobs ( ) . await ;
loop {
manager . scheduler . tick ( ) ;
2024-09-24 20:29:22 -04:00
std ::thread ::sleep ( std ::time ::Duration ::from_millis ( 500 ) ) ;
2024-09-22 04:10:29 -04:00
}
2024-09-03 01:17:19 -04:00
}
2024-09-21 23:57:37 -04:00
2024-09-22 04:10:29 -04:00
impl < ' a > TaskManager < ' a > {
fn new ( pool : Pool < Postgres > ) -> Self {
TaskManager {
pool ,
2024-09-21 23:57:37 -04:00
jobs : Vec ::new ( ) ,
last_activated : None ,
last_job : None ,
2024-09-22 04:10:29 -04:00
scheduler : job_scheduler ::JobScheduler ::new ( ) ,
2024-09-21 23:57:37 -04:00
}
}
2024-09-22 04:10:29 -04:00
pub async fn register_jobs ( & self ) {
// let jobs: Vec<Job> = Vec::new();
let results = sqlx ::query_as ::< _ , TaskJob > ( " SELECT task_id, task_name, schedule, is_active, created_at, deleted_at FROM tasks WHERE is_active = true AND deleted_at IS NULL " )
. fetch_all ( & self . pool )
. await
. unwrap ( ) ;
let mut scheduler = job_scheduler ::JobScheduler ::new ( ) ;
2024-10-04 07:21:10 -04:00
results . iter ( ) . for_each ( | r | {
println! ( " Registering job: {:?} " , r . task_name ) ;
let job : _ = job_scheduler ::Job ::new ( r . schedule . parse ( ) . unwrap ( ) , | | {
match r . task_id {
1 = > import_posts ::register ( & Arc ::new ( & self . pool ) ) ,
2024-09-24 20:29:22 -04:00
_ = > panic! ( ) ,
2024-10-04 07:21:10 -04:00
}
} ) ;
scheduler . add ( job ) ;
} ) ;
2024-09-21 23:57:37 -04:00
}
}