systemprompt_generator/jobs/
page_prerender.rs1use async_trait::async_trait;
8use std::sync::Arc;
9use systemprompt_content::ContentRepository;
10use systemprompt_database::DbPool;
11use systemprompt_models::AppPaths;
12use systemprompt_provider_contracts::{Job, JobContext, JobResult, ProviderError, ProviderResult};
13
14use crate::prerender::prerender_pages;
15
16#[derive(Debug, Clone, Copy)]
17pub struct PagePrerenderJob;
18
19#[async_trait]
20impl Job for PagePrerenderJob {
21 fn name(&self) -> &'static str {
22 "page_prerender"
23 }
24
25 fn description(&self) -> &'static str {
26 "Prerenders all registered page prerenderers to static HTML"
27 }
28
29 fn schedule(&self) -> &'static str {
30 "0 30 4 * * *"
31 }
32
33 async fn execute(&self, ctx: &JobContext) -> ProviderResult<JobResult> {
34 let start_time = std::time::Instant::now();
35 let db_pool = Arc::clone(ctx.db_pool::<DbPool>().ok_or_else(|| {
36 ProviderError::Configuration("DbPool not available in job context".into())
37 })?);
38 let paths = ctx
39 .app_paths::<Arc<AppPaths>>()
40 .ok_or_else(|| {
41 ProviderError::Configuration("AppPaths not available in job context".into())
42 })?
43 .as_ref();
44
45 tracing::info!("Job started");
46 let content_repo = ContentRepository::new(&db_pool)
47 .map_err(|e| ProviderError::Configuration(e.to_string()))?;
48 let results = prerender_pages(db_pool, content_repo, paths)
49 .await
50 .map_err(|e| ProviderError::RenderFailed(e.to_string()))?;
51 let pages_rendered = results.len() as u64;
52 let duration_ms = start_time.elapsed().as_millis() as u64;
53
54 tracing::info!(
55 pages_rendered = pages_rendered,
56 duration_ms = duration_ms,
57 "Job completed"
58 );
59
60 Ok(JobResult::success()
61 .with_stats(pages_rendered, 0)
62 .with_duration(duration_ms))
63 }
64}
65
66systemprompt_provider_contracts::submit_job!(&PagePrerenderJob);