Skip to main content

systemprompt_generator/jobs/
content_prerender.rs

1//! Scheduled job that runs the content prerender pipeline once a day.
2//!
3//! Copyright (c) systemprompt.io — Business Source License 1.1.
4//! See <https://systemprompt.io> for licensing details.
5
6use async_trait::async_trait;
7use std::sync::Arc;
8use systemprompt_content::ContentRepository;
9use systemprompt_database::DbPool;
10use systemprompt_models::AppPaths;
11use systemprompt_provider_contracts::{Job, JobContext, JobResult, ProviderError, ProviderResult};
12
13use crate::prerender::prerender_content;
14
15#[derive(Debug, Clone, Copy)]
16pub struct ContentPrerenderJob;
17
18#[async_trait]
19impl Job for ContentPrerenderJob {
20    fn name(&self) -> &'static str {
21        "content_prerender"
22    }
23
24    fn description(&self) -> &'static str {
25        "Prerenders all configured content sources to static HTML"
26    }
27
28    fn schedule(&self) -> &'static str {
29        "0 0 4 * * *"
30    }
31
32    async fn execute(&self, ctx: &JobContext) -> ProviderResult<JobResult> {
33        let start_time = std::time::Instant::now();
34        let db_pool = Arc::clone(ctx.db_pool::<DbPool>().ok_or_else(|| {
35            ProviderError::Configuration("DbPool not available in job context".into())
36        })?);
37        let paths = ctx
38            .app_paths::<Arc<AppPaths>>()
39            .ok_or_else(|| {
40                ProviderError::Configuration("AppPaths not available in job context".into())
41            })?
42            .as_ref();
43
44        tracing::info!("Job started");
45        let content_repo = ContentRepository::new(&db_pool)
46            .map_err(|e| ProviderError::Configuration(e.to_string()))?;
47        prerender_content(db_pool, content_repo, paths)
48            .await
49            .map_err(|e| ProviderError::RenderFailed(e.to_string()))?;
50        let duration_ms = start_time.elapsed().as_millis() as u64;
51        tracing::info!(duration_ms = duration_ms, "Job completed");
52
53        Ok(JobResult::success().with_duration(duration_ms))
54    }
55}
56
57systemprompt_provider_contracts::submit_job!(&ContentPrerenderJob);