(* Background scheduler for website monitoring *) open Lwt.Infix (* Check intervals in seconds *) let default_check_interval = 300 (* 5 minutes *) (* Scheduler state *) type scheduler_state = { mutable running: bool; thread_id: Lwt.t unit; } let scheduler_state = { running = false; thread_id = Lwt.return_unit; } (* Convert check interval to microseconds *) let interval_to_usecs interval = interval * 1_000_000 (* Check websites that are due for monitoring *) let check_due_websites () : unit Lwt.t = Monitor.check_all_active_websites () (* Cleanup old history records *) let cleanup_old_history () : unit Lwt.t = Database.Websites.get_all () >>= fun websites -> let retention_days = 30 in Lwt_list.iter_s (fun (website : Database.Website.t) -> Database.CheckHistories.cleanup_old_website_history website.id retention_days) websites >>= fun () -> Logs.app (fun m -> m "Completed cleanup of old history records"); Lwt.return_unit (* Main scheduler loop *) let scheduler_loop () : unit Lwt.t = Logs.app (fun m -> m "Scheduler started"); let rec loop () = if not scheduler_state.running then Lwt.return_unit else check_due_websites () >>= fun () -> (* Every 10 iterations, cleanup old history *) (* You could track this more elegantly *) cleanup_old_history () >>= fun () -> (* Sleep for 1 minute, then check again *) Lwt_unix.sleep 60.0 >>= fun () -> loop () in loop () (* Start the scheduler *) let start () : unit = if scheduler_state.running then Logs.warn (fun m -> m "Scheduler already running") else begin scheduler_state.running <- true; scheduler_state.thread_id <- Lwt.async (fun () -> scheduler_loop () >>= fun () -> Logs.app (fun m -> m "Scheduler stopped"); Lwt.return_unit); Logs.app (fun m -> m "Scheduler started successfully") end (* Stop the scheduler *) let stop () : unit Lwt.t = scheduler_state.running <- false; Logs.app (fun m -> m "Scheduler stop requested"); (* Wait for scheduler to finish current iteration *) Lwt.return_unit (* Get scheduler status *) let status () : Yojson.Basic.t = Yojson.Basic.( `Assoc [ ("running", `Bool scheduler_state.running); ])