feat(admin): observability — job history, live now-analyzing, durations & metrics (0.84.0) (#6)
This commit was merged in pull request #6.
This commit is contained in:
@@ -197,8 +197,69 @@ where
|
||||
/// On any failure the chapter stays at `page_count = 0` (no partial
|
||||
/// rows) and the blobs already written are deleted best-effort by
|
||||
/// [`cleanup_orphans`], so a retry starts clean.
|
||||
/// Timing wrapper over [`sync_chapter_content_inner`]: records one `chapter`
|
||||
/// row in `crawl_metrics` with the wall-clock and outcome. Best-effort — a
|
||||
/// metrics-write failure never fails the chapter sync. `Skipped` /
|
||||
/// `SessionExpired` perform no fetch, so they aren't timed.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn sync_chapter_content(
|
||||
browser: &chromiumoxide::Browser,
|
||||
db: &PgPool,
|
||||
storage: &dyn Storage,
|
||||
http: &reqwest::Client,
|
||||
rate: &HostRateLimiters,
|
||||
chapter_id: Uuid,
|
||||
manga_id: Uuid,
|
||||
source_url: &str,
|
||||
force_refetch: bool,
|
||||
allowlist: &DownloadAllowlist,
|
||||
max_image_bytes: usize,
|
||||
tor: Option<&crate::crawler::tor::TorController>,
|
||||
progress: Option<&crate::crawler::status::StatusHandle>,
|
||||
enqueue_analysis: bool,
|
||||
) -> anyhow::Result<SyncOutcome> {
|
||||
let started = std::time::Instant::now();
|
||||
let result = sync_chapter_content_inner(
|
||||
browser, db, storage, http, rate, chapter_id, manga_id, source_url,
|
||||
force_refetch, allowlist, max_image_bytes, tor, progress, enqueue_analysis,
|
||||
)
|
||||
.await;
|
||||
let duration_ms = started.elapsed().as_millis() as i64;
|
||||
match &result {
|
||||
Ok(SyncOutcome::Fetched { pages }) => {
|
||||
let _ = crate::repo::crawl_metrics::record(
|
||||
db,
|
||||
crate::repo::crawl_metrics::OP_CHAPTER,
|
||||
Some(manga_id),
|
||||
Some(chapter_id),
|
||||
"ok",
|
||||
duration_ms,
|
||||
Some(*pages as i32),
|
||||
None,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
Err(e) => {
|
||||
let _ = crate::repo::crawl_metrics::record(
|
||||
db,
|
||||
crate::repo::crawl_metrics::OP_CHAPTER,
|
||||
Some(manga_id),
|
||||
Some(chapter_id),
|
||||
"failed",
|
||||
duration_ms,
|
||||
None,
|
||||
Some(&format!("{e:#}")),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
// Skipped / SessionExpired: no fetch performed → not a timed op.
|
||||
Ok(_) => {}
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
async fn sync_chapter_content_inner(
|
||||
browser: &chromiumoxide::Browser,
|
||||
db: &PgPool,
|
||||
storage: &dyn Storage,
|
||||
|
||||
Reference in New Issue
Block a user