feat(job-registry): wire /api/admin/jobs/*
This commit is contained in:
@@ -3124,7 +3124,7 @@ impl DedupPort for DedupService {
|
||||
|
||||
/// 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`).
|
||||
/// and admin URLs (`POST /api/admin/jobs/dedup_gc/trigger`).
|
||||
pub const DEDUP_GC_JOB_NAME: &str = "dedup_gc";
|
||||
|
||||
#[async_trait::async_trait]
|
||||
@@ -3136,7 +3136,7 @@ impl crate::infrastructure::scheduler::JobHandler for DedupService {
|
||||
/// 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`.
|
||||
/// `POST /api/admin/jobs/dedup_gc/trigger`.
|
||||
///
|
||||
/// Registered with `interval = None` (on-demand only): the periodic
|
||||
/// tick belongs to trash cleanup, whose sweep already runs GC as
|
||||
@@ -3148,12 +3148,28 @@ impl crate::infrastructure::scheduler::JobHandler for DedupService {
|
||||
/// `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 {
|
||||
///
|
||||
/// `args.force = true` skips the orphan grace window
|
||||
/// (`garbage_collect_force` — grace_secs = 0), matching the legacy
|
||||
/// `POST /admin/internal/trigger-gc?force=true` semantics. Unsafe
|
||||
/// under concurrent uploads: only reachable through the admin
|
||||
/// endpoint and only intentionally used by tests + operator
|
||||
/// diagnostic sessions.
|
||||
async fn run(
|
||||
&self,
|
||||
args: &crate::infrastructure::scheduler::JobRunArgs,
|
||||
) -> 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 }))
|
||||
}
|
||||
let result = if args.force {
|
||||
self.garbage_collect_force().await
|
||||
} else {
|
||||
self.garbage_collect().await
|
||||
};
|
||||
match result {
|
||||
Ok((items, bytes)) => JobOutcome::ok_with(
|
||||
items,
|
||||
serde_json::json!({ "bytes_reclaimed": bytes, "forced": args.force }),
|
||||
),
|
||||
Err(e) => JobOutcome::Err(format!("dedup GC failed: {e}")),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ use tracing::{error, info};
|
||||
|
||||
use crate::application::ports::authorization_ports::AuthorizationEngine;
|
||||
use crate::common::errors::DomainError;
|
||||
use crate::infrastructure::scheduler::{JobHandler, JobOutcome};
|
||||
use crate::infrastructure::scheduler::{JobHandler, JobOutcome, JobRunArgs};
|
||||
use crate::infrastructure::services::pg_acl_engine::PgAclEngine;
|
||||
use async_trait::async_trait;
|
||||
|
||||
@@ -112,19 +112,26 @@ impl JobHandler for GrantCleanupService {
|
||||
GRANT_CLEANUP_JOB_NAME
|
||||
}
|
||||
|
||||
/// Runs one purge with the configured grace window. `count` on the
|
||||
/// returned `JobOutcome::Ok` is the number of `role_grants` rows
|
||||
/// physically deleted; `extra.grace_days` records which grace was
|
||||
/// applied so admin listings can see it without a second lookup.
|
||||
/// Runs one purge. `count` on the returned `JobOutcome::Ok` is
|
||||
/// the number of `role_grants` rows physically deleted;
|
||||
/// `extra.grace_days` records which grace was applied so admin
|
||||
/// listings can see it without a second lookup.
|
||||
///
|
||||
/// Admin `?force=true` (grace = 0) does NOT come through here —
|
||||
/// that path calls `purge(Some(0))` directly on the shared
|
||||
/// `Arc<GrantCleanupService>` from the handler.
|
||||
async fn run(&self) -> JobOutcome {
|
||||
match self.purge(None).await {
|
||||
Ok(count) => {
|
||||
JobOutcome::ok_with(count, serde_json::json!({ "grace_days": self.grace_days }))
|
||||
}
|
||||
/// `args.force = true` collapses the grace window to zero for
|
||||
/// this run only — matches the legacy
|
||||
/// `POST /admin/internal/trigger-grant-cleanup?force=true` shape.
|
||||
/// The configured `self.grace_days` is not mutated.
|
||||
async fn run(&self, args: &JobRunArgs) -> JobOutcome {
|
||||
let grace_override = if args.force { Some(0) } else { None };
|
||||
let effective_grace = grace_override.unwrap_or(self.grace_days);
|
||||
match self.purge(grace_override).await {
|
||||
Ok(count) => JobOutcome::ok_with(
|
||||
count,
|
||||
serde_json::json!({
|
||||
"grace_days": effective_grace,
|
||||
"forced": args.force,
|
||||
}),
|
||||
),
|
||||
Err(e) => JobOutcome::Err(format!("grant cleanup failed: {e}")),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ use tracing::{debug, error, info, instrument};
|
||||
use crate::common::errors::Result;
|
||||
use crate::domain::repositories::trash_repository::TrashRepository;
|
||||
use crate::infrastructure::repositories::pg::trash_db_repository::TrashDbRepository;
|
||||
use crate::infrastructure::scheduler::{JobHandler, JobOutcome};
|
||||
use crate::infrastructure::scheduler::{JobHandler, JobOutcome, JobRunArgs};
|
||||
use crate::infrastructure::services::dedup_service::DedupService;
|
||||
use async_trait::async_trait;
|
||||
|
||||
@@ -165,7 +165,11 @@ impl JobHandler for TrashCleanupService {
|
||||
///
|
||||
/// Failure of the trash sweep itself → `Err`. GC failure alone is
|
||||
/// non-fatal and stays logged only.
|
||||
async fn run(&self) -> JobOutcome {
|
||||
///
|
||||
/// `args.force` is ignored — trash cleanup has no acceleration
|
||||
/// concept (retention windows are per-item metadata, not a runtime
|
||||
/// knob).
|
||||
async fn run(&self, _args: &JobRunArgs) -> JobOutcome {
|
||||
match self.run_once().await {
|
||||
Ok(stats) => {
|
||||
let removed = stats.files_purged + stats.folders_purged;
|
||||
|
||||
Reference in New Issue
Block a user