201 lines
3.7 KiB
JavaScript
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;
|
|
});
|