RAG: ночная пакетная индексация эмбеддингов, очередь embedding_queue, MCP get_organization_context, снижение OLLAMA_KEEP_ALIVE
This commit is contained in:
@@ -1117,6 +1117,60 @@ async function runStartupDataPatches() {
|
||||
}, 30_000);
|
||||
log('Billing worker started (24h interval)');
|
||||
|
||||
// Embedding queue worker — process deferred RAG embeddings nightly at 23:00 MSK
|
||||
function getMsUntilMskHour(targetHour: number): number {
|
||||
const now = new Date();
|
||||
const formatter = new Intl.DateTimeFormat('en-US', {
|
||||
timeZone: 'Europe/Moscow',
|
||||
year: 'numeric',
|
||||
month: 'numeric',
|
||||
day: 'numeric',
|
||||
hour: 'numeric',
|
||||
minute: 'numeric',
|
||||
second: 'numeric',
|
||||
hour12: false,
|
||||
});
|
||||
const parts = formatter.formatToParts(now);
|
||||
const getPart = (type: string) => parseInt(parts.find(p => p.type === type)?.value ?? '0', 10);
|
||||
const year = getPart('year');
|
||||
const month = getPart('month') - 1;
|
||||
const day = getPart('day');
|
||||
const hour = getPart('hour');
|
||||
const minute = getPart('minute');
|
||||
const second = getPart('second');
|
||||
const mskNow = new Date(year, month, day, hour, minute, second).getTime();
|
||||
let mskTarget = new Date(year, month, day, targetHour, 0, 0).getTime();
|
||||
if (mskTarget <= mskNow) {
|
||||
mskTarget += 24 * 60 * 60 * 1000;
|
||||
}
|
||||
return mskTarget - mskNow;
|
||||
}
|
||||
|
||||
async function runEmbeddingQueueWorker() {
|
||||
try {
|
||||
const { processEmbeddingQueue } = await import('./services/embedding.service');
|
||||
const pending = await storage.getPendingEmbeddingQueue(10_000);
|
||||
if (pending.length === 0) {
|
||||
log('[RAG Queue] No pending embeddings');
|
||||
return;
|
||||
}
|
||||
log(`[RAG Queue] Processing ${pending.length} pending embedding items`);
|
||||
const result = await processEmbeddingQueue(storage, pending);
|
||||
const ids = pending.map(i => i.id);
|
||||
await storage.markEmbeddingQueueProcessed(ids);
|
||||
log(`[RAG Queue] Done: attempted=${result.attempted}, succeeded=${result.succeeded}, failed=${result.failed}`);
|
||||
} catch (err) {
|
||||
log(`[RAG Queue] Worker error: ${err instanceof Error ? err.message : String(err)}`);
|
||||
}
|
||||
}
|
||||
|
||||
const msUntil23Msk = getMsUntilMskHour(23);
|
||||
setTimeout(() => {
|
||||
runEmbeddingQueueWorker();
|
||||
setInterval(runEmbeddingQueueWorker, 24 * 60 * 60 * 1000);
|
||||
}, msUntil23Msk);
|
||||
log(`Embedding queue worker scheduled at 23:00 MSK (in ${Math.round(msUntil23Msk / 1000 / 60)} minutes)`);
|
||||
|
||||
// ALWAYS serve the app on the port specified in the environment variable PORT
|
||||
// Other ports are firewalled. Default to 5000 if not specified.
|
||||
// this serves both the API and the client.
|
||||
|
||||
Reference in New Issue
Block a user