gallery_server_client_s190js/tools/taskTimer.js
2026-10-26 11:00:14 +01:00

201 lines
3.7 KiB
JavaScript

// tools/taskTimer.js
require('dotenv').config();
const db = require('../db/knex');
const {
runCycle: runFaceClusteringCycle,
} = require(
'./runFaceClusteringScheduler'
);
const {
cleanupCast,
} = require(
'./cleanupCast'
);
/*
* Face clustering:
* ogni ora.
*/
const CLUSTER_INTERVAL_MS =
60 * 60 * 1000;
/*
* Cleanup Cast:
* una volta al giorno.
*/
const CLEANUP_INTERVAL_MS =
24 * 60 * 60 * 1000;
let clusterRunning = false;
let cleanupRunning = false;
/*
* ============================================================
* FACE CLUSTERING
* ============================================================
*/
async function runClustering() {
if (clusterRunning) {
console.log(
'[taskTimer] clustering already running, skip'
);
return;
}
clusterRunning = true;
const startedAt = Date.now();
console.log(
'[taskTimer] clustering cycle start'
);
try {
await runFaceClusteringCycle();
console.log(
'[taskTimer] clustering cycle completed',
`elapsedMs=${Date.now() - startedAt}`,
);
} catch (error) {
console.error(
'[taskTimer] clustering cycle error',
error,
);
} finally {
clusterRunning = false;
}
}
/*
* ============================================================
* CLEANUP CAST
* ============================================================
*/
async function runCleanup() {
if (cleanupRunning) {
console.log('[taskTimer] cleanup already running, skip');
return;
}
cleanupRunning = true;
const startedAt = Date.now();
console.log('[taskTimer] cleanup cycle start');
try {
// Mantiene la pulizia HLS/Cast esistente.
try {
await cleanupCast({ dryRun: false });
} catch (error) {
console.error('[taskTimer] cleanup Cast error', error);
}
// Elimina solo job terminali completati da oltre 24 ore.
for (const table of [
'photo_ingest_jobs',
'activity_ingest_jobs',
]) {
try {
if (!(await db.schema.hasTable(table))) {
console.warn(`[taskTimer] table not found: ${table}`);
continue;
}
const deleted = await db(table)
.whereIn('status', ['done', 'error'])
.whereNotNull('completed_at')
.whereRaw(
"datetime(completed_at) < datetime('now', '-24 hours')"
)
.del();
console.log(
`[taskTimer] ${table}: removed ${deleted} expired jobs`
);
} catch (error) {
console.error(`[taskTimer] ${table} cleanup error`, error);
}
}
console.log(
'[taskTimer] cleanup cycle completed',
`elapsedMs=${Date.now() - startedAt}`,
);
} finally {
cleanupRunning = false;
}
}
/*
* ============================================================
* MAIN
* ============================================================
*/
async function main() {
console.log(
'[taskTimer] started'
);
console.log(
'[taskTimer] clustering interval:',
`${CLUSTER_INTERVAL_MS / 60000} minutes`,
);
console.log(
'[taskTimer] cleanup interval:',
`${CLEANUP_INTERVAL_MS / 3600000} hours`,
);
/*
* Clustering immediato all'avvio.
*/
await runClustering();
/*
* Cleanup anche all'avvio.
*
* ATTENZIONE:
* cleanupCast garantisce comunque che file
* con meno di 24 ore non vengano cancellati.
*/
await runCleanup();
setInterval(
() => {
void runClustering();
},
CLUSTER_INTERVAL_MS,
);
setInterval(
() => {
void runCleanup();
},
CLEANUP_INTERVAL_MS,
);
console.log(
'[taskTimer] timers armed'
);
}
main().catch((error) => {
console.error(
'[taskTimer] fatal error',
error,
);
process.exitCode = 1;
});