Skip to main content

max / makenotwork

1.2 KB · 43 lines History Blame Raw
1 //! Scheduler job-run ledger: record each background job tick (name +
2 //! rows_affected + timestamp) and read the recent runs for the admin/health view.
3
4 use chrono::{DateTime, Utc};
5 use sqlx::{FromRow, PgPool};
6
7 use crate::error::Result;
8
9 #[derive(FromRow)]
10 pub(crate) struct SchedulerJobRun {
11 pub job_name: String,
12 pub last_ran_at: DateTime<Utc>,
13 pub rows_affected: i64,
14 }
15
16 /// Upsert the last-run timestamp and rows affected for a scheduled job.
17 pub(crate) async fn record_job_run(
18 pool: &PgPool,
19 job_name: &str,
20 rows_affected: i64,
21 ) -> Result<()> {
22 sqlx::query(
23 "INSERT INTO scheduler_job_runs (job_name, last_ran_at, rows_affected)
24 VALUES ($1, NOW(), $2)
25 ON CONFLICT (job_name) DO UPDATE SET last_ran_at = NOW(), rows_affected = $2",
26 )
27 .bind(job_name)
28 .bind(rows_affected)
29 .execute(pool)
30 .await?;
31 Ok(())
32 }
33
34 /// Fetch all job run records for health page display.
35 pub(crate) async fn get_job_runs(pool: &PgPool) -> Result<Vec<SchedulerJobRun>> {
36 let rows = sqlx::query_as::<_, SchedulerJobRun>(
37 "SELECT job_name, last_ran_at, rows_affected FROM scheduler_job_runs ORDER BY job_name",
38 )
39 .fetch_all(pool)
40 .await?;
41 Ok(rows)
42 }
43