feat(job-registry): wire dedub_gc
This commit is contained in:
@@ -1277,6 +1277,27 @@ impl AppServiceFactory {
|
|||||||
// 1. Core services (PgPool needed for DedupService index)
|
// 1. Core services (PgPool needed for DedupService index)
|
||||||
let core = self.create_core_services(&pool, &maintenance_pool).await?;
|
let core = self.create_core_services(&pool, &maintenance_pool).await?;
|
||||||
|
|
||||||
|
// Register on-demand-only jobs whose owning service lives on
|
||||||
|
// CoreServices. Dedup GC has NO periodic tick — trash cleanup's
|
||||||
|
// sweep already runs GC as its tail step, so a periodic dedup
|
||||||
|
// schedule would double the work. Registering with `interval =
|
||||||
|
// None` keeps it admin-triggerable through the uniform scheduler
|
||||||
|
// surface (`POST /api/admin/internal/trigger-job/dedup_gc`).
|
||||||
|
if let Err(e) = core
|
||||||
|
.job_registry
|
||||||
|
.register(
|
||||||
|
core.dedup_service.clone()
|
||||||
|
as Arc<dyn crate::infrastructure::scheduler::JobHandler>,
|
||||||
|
None, // on-demand only
|
||||||
|
None, // no timeout
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
tracing::error!("Failed to register dedup_gc job with scheduler: {e}");
|
||||||
|
} else {
|
||||||
|
tracing::info!("Dedup GC registered with scheduler (on-demand only)");
|
||||||
|
}
|
||||||
|
|
||||||
// 2. Repository services (requires PgPool for all metadata)
|
// 2. Repository services (requires PgPool for all metadata)
|
||||||
let repos = self.create_repository_services(&core, &pool);
|
let repos = self.create_repository_services(&core, &pool);
|
||||||
|
|
||||||
|
|||||||
@@ -3120,6 +3120,46 @@ impl DedupPort for DedupService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ─── JobRegistry integration ────────────────────────────────────────────────
|
||||||
|
|
||||||
|
/// Registered name for the dedup GC job. Stable identifier used in
|
||||||
|
/// log lines, `admin.background_runs.job_name` (when Part 2 lands),
|
||||||
|
/// and admin URLs (`POST /api/admin/internal/trigger-job/dedup_gc`).
|
||||||
|
pub const DEDUP_GC_JOB_NAME: &str = "dedup_gc";
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
impl crate::infrastructure::scheduler::JobHandler for DedupService {
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
DEDUP_GC_JOB_NAME
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Runs one `garbage_collect` sweep — the same reclamation that
|
||||||
|
/// `TrashCleanupService` invokes inline as its tail step, exposed
|
||||||
|
/// through the scheduler so operators can trigger it uniformly via
|
||||||
|
/// `POST /api/admin/internal/trigger-job/dedup_gc`.
|
||||||
|
///
|
||||||
|
/// Registered with `interval = None` (on-demand only): the periodic
|
||||||
|
/// tick belongs to trash cleanup, whose sweep already runs GC as
|
||||||
|
/// its final phase. Registering a redundant periodic tick here
|
||||||
|
/// would double the reclamation work with no benefit; the admin
|
||||||
|
/// trigger is what the registered entry buys us — uniform log lines,
|
||||||
|
/// panic containment, exclusivity vs. any concurrent trigger.
|
||||||
|
///
|
||||||
|
/// `count` reports blobs reclaimed; `extra.bytes_reclaimed` reports
|
||||||
|
/// the freed disk. GC returning `(0, 0)` is normal — it means trash
|
||||||
|
/// cleanup already reaped everything.
|
||||||
|
async fn run(&self) -> crate::infrastructure::scheduler::JobOutcome {
|
||||||
|
use crate::infrastructure::scheduler::JobOutcome;
|
||||||
|
match self.garbage_collect().await {
|
||||||
|
Ok((items, bytes)) => JobOutcome::ok_with(
|
||||||
|
items,
|
||||||
|
serde_json::json!({ "bytes_reclaimed": bytes }),
|
||||||
|
),
|
||||||
|
Err(e) => JobOutcome::Err(format!("dedup GC failed: {e}")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ─── Tests ───────────────────────────────────────────────────────────────────
|
// ─── Tests ───────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
Reference in New Issue
Block a user