37 lines
1.6 KiB
JavaScript
37 lines
1.6 KiB
JavaScript
const { parentPort, workerData } = require('node:worker_threads');
|
|
const Database = require('better-sqlite3');
|
|
|
|
try {
|
|
const db = new Database(workerData.databasePath, { readonly: true, fileMustExist: true });
|
|
const counts = db.prepare(`
|
|
SELECT
|
|
COALESCE((SELECT seq FROM sqlite_sequence WHERE name='articles'), 0) AS total,
|
|
(SELECT COUNT(*) FROM article_embedding_meta) AS withContent,
|
|
(SELECT COUNT(*) FROM article_embedding_meta) AS withEmbedding,
|
|
COALESCE((SELECT seq FROM sqlite_sequence WHERE name='events'), 0) AS eventCount,
|
|
(SELECT COUNT(*) FROM articles WHERE ingested_at >= datetime('now', '-1 hour')) AS ingestedPerHour,
|
|
(SELECT COUNT(*) FROM article_embedding_meta WHERE embedded_at >= datetime('now', '-1 hour')) AS contentPerHour
|
|
`).get();
|
|
const bySource = db.prepare(`
|
|
SELECT source, COUNT(*) AS n FROM articles GROUP BY source ORDER BY n DESC
|
|
`).all();
|
|
// Avoid scanning the 3.7 GB article table for legacy content-status values.
|
|
// Readiness is the useful operational distinction and is available from the
|
|
// compact embedding metadata table.
|
|
const byStatus = [
|
|
{ status: 'ready', n: counts.withEmbedding },
|
|
{ status: 'unprocessed', n: Math.max(0, counts.total - counts.withEmbedding) },
|
|
];
|
|
let embeddingsPerHour = 0;
|
|
try {
|
|
embeddingsPerHour = db.prepare(`
|
|
SELECT COUNT(*) AS n FROM article_embedding_meta
|
|
WHERE embedded_at >= datetime('now', '-1 hour')
|
|
`).get().n;
|
|
} catch (_) {}
|
|
db.close();
|
|
parentPort.postMessage({ value: { ...counts, bySource, byStatus, embeddingsPerHour } });
|
|
} catch (error) {
|
|
parentPort.postMessage({ error: error.message });
|
|
}
|