feat: zamanlayıcı teşhis ucu + geniş arşiv dolumu

- /api/health/scheduler: DT/sonuç taraması durumu, son DT turu, boş bellek,
  Chromium varlığı — uzaktan teşhis için
- Dolum eşiği 2.000 → 25.000, pencere 180 → 365 gün (arşiv 6 aylık havuzun
  %7'sinde erken duruyordu)
This commit is contained in:
2026-08-28 22:37:11 +03:00
parent 1838de95f5
commit 5282543471
2 changed files with 27 additions and 3 deletions
+4 -1
View File
@@ -22,7 +22,7 @@ import { aiConfigured, availableProviders, analyzeSpec } from './ai.mjs';
import { billingConfigured, planCatalog, createCheckoutSession } from './billing.mjs';
import { searchTed } from './ted.mjs';
import { readHistory, historyStats } from './history-store.mjs';
import { startScheduler } from './scheduler.mjs';
import { startScheduler, schedulerStatus } from './scheduler.mjs';
import { searchKik, kararMetni } from './kik.mjs';
import { documentUrl, ilanMetni, documentText, browserAvailable } from './documents.mjs';
@@ -577,6 +577,9 @@ const server = http.createServer(async (req, res) => {
}
if (url.pathname === '/api/health') return json(res, 200, { ok: true });
if (url.pathname === '/api/health/scheduler') {
return json(res, 200, { success: true, tarayiciVar: await browserAvailable(), ...schedulerStatus() });
}
return json(res, 404, { success: false, error: 'not found' });
} catch (err) {
+23 -2
View File
@@ -23,10 +23,10 @@ let calisiyor = false;
function tarataParams() {
const s = historyStats();
const mevcut = s.available ? (s.toplam || 0) : 0;
const esik = Number(process.env.SCAN_BACKFILL_ESIK || 2000);
const esik = Number(process.env.SCAN_BACKFILL_ESIK || 25000);
if (mevcut < esik) {
return {
gun: process.env.SCAN_BACKFILL_GUN || '180',
gun: process.env.SCAN_BACKFILL_GUN || '365',
limit: process.env.SCAN_BACKFILL_LIMIT || '1500',
tip: `geçmiş dolumu (arşivde ${mevcut} kayıt)`,
};
@@ -76,6 +76,8 @@ function kalemDoldur() {
// --- Doğrudan temin (Playwright/Chromium gerektirir) ---
let dtCalisiyor = false;
let dtSonTur = null; // { baslangic, bitis, kod, hata }
let dtSonrakiMs = null;
// Chromium ~350MB RSS kullanabilir; sunucu darsa DT'yi atla ve uyar.
function bellekYeterliMi() {
@@ -96,6 +98,7 @@ function dtTara() {
}
if (!bellekYeterliMi()) return;
dtCalisiyor = true;
dtSonTur = { baslangic: new Date().toISOString() };
const pages = process.env.DT_PAGES || '5';
const details = process.env.DT_DETAILS || '30';
console.log(`[scheduler] doğrudan temin taraması başlıyor (${pages} sayfa, ${details} detay)`);
@@ -107,15 +110,33 @@ function dtTara() {
p.stderr.on('data', (d) => process.stderr.write(String(d)));
p.on('close', (code) => {
dtCalisiyor = false;
dtSonTur = { ...(dtSonTur || {}), bitis: new Date().toISOString(), kod: code };
if (code !== 0) console.warn(`[scheduler] ⚠ DT taraması ${code} koduyla bitti — Chromium kurulu mu / bellek yeterli mi kontrol edin.`);
else console.log('[scheduler] DT taraması bitti');
});
p.on('error', (e) => {
dtCalisiyor = false;
dtSonTur = { ...(dtSonTur || {}), bitis: new Date().toISOString(), hata: e.message };
console.warn('[scheduler] ⚠ DT worker başlatılamadı:', e.message, '— Chromium yoksa DT_ENABLED=0 yapın.');
});
}
export function schedulerStatus() {
const bosMB = Math.round(os.freemem() / 1024 / 1024);
return {
sonucTaramasi: { aktif: process.env.SCAN_ENABLED !== '0', calisiyor: calisiyor, aralikSaat: Number(process.env.SCAN_INTERVAL_SAAT || 6) },
dogrudanTemin: {
aktif: process.env.DT_ENABLED !== '0',
calisiyor: dtCalisiyor,
aralikSaat: Number(process.env.DT_INTERVAL_SAAT || 4),
sonTur: dtSonTur,
bellekEsigiMB: Number(process.env.DT_MIN_BOS_MB || 600),
},
bosBellekMB: bosMB,
toplamBellekMB: Math.round(os.totalmem() / 1024 / 1024),
};
}
export function startScheduler() {
if (process.env.SCAN_ENABLED === '0') {
console.log('[scheduler] devre dışı (SCAN_ENABLED=0)');