perf: DT detaylari 10 paralel + adaptif fren (0.36 -> 3.2 kayit/sn) & feat: EKAP'tan inen dokumani ihaleye yukleme

This commit is contained in:
2026-08-30 14:07:29 +03:00
parent c5662d2e60
commit 40fea290e4
5 changed files with 183 additions and 29 deletions
+41 -11
View File
@@ -36,7 +36,10 @@ const argVal = (name, def) => {
return i >= 0 && args[i + 1] ? Number(args[i + 1]) : def;
};
const MAX_PAGES = argVal('--pages', 10);
const MAX_DETAILS = argVal('--details', 250);
const MAX_DETAILS = argVal('--details', 1500);
// Detaylar PARALEL çekilir; asıl darboğaz istek başına bekleme idi.
const DETAY_PARALEL = Number(process.env.DT_PARALEL || argVal('--paralel', 10));
const DETAY_GECIKME_MS = Number(process.env.DT_GECIKME_MS || 400);
const DELAY_BASE_MS = 2000;
const DELAY_JITTER_MS = 1500;
@@ -262,7 +265,10 @@ async function run() {
await humanDelay();
}
// 2) Eksik detaylar
// 2) Eksik detaylar — paralel + adaptif fren
// EKAP'ı zorlamamak için: her turda DETAY_PARALEL istek eş zamanlı,
// aralarda kısa duraklama. Sunucu direnç gösterirse (challenge/hata)
// gecikme kendiliğinden büyür, temiz turlarda tekrar daralır.
const pending = db
.prepare(
// EN YENİ kayıtlar önce: arayüz en yeni 5000'i gösteriyor; varsayılan
@@ -273,18 +279,42 @@ async function run() {
ORDER BY rowid DESC LIMIT ?`,
)
.all(MAX_DETAILS);
console.log(`[dt-worker] ${pending.length} detay çekilecek`);
console.log(`[dt-worker] ${pending.length} detay çekilecek (${DETAY_PARALEL} paralel)`);
let ok = 0;
for (const row of pending) {
try {
const detail = await fetchDetail(sess, row.dogrudan_temin_id, row.idare_id);
setDetail.run(JSON.stringify(detail), row.dogrudan_temin_id);
ok++;
} catch (err) {
console.warn(`[dt-worker] detay hatası (${row.dogrudan_temin_id}): ${err.message}`);
let hata = 0;
let gecikme = DETAY_GECIKME_MS;
const basladi = Date.now();
for (let i = 0; i < pending.length; i += DETAY_PARALEL) {
const grup = pending.slice(i, i + DETAY_PARALEL);
const sonuc = await Promise.all(
grup.map(async (row) => {
try {
const detail = await fetchDetail(sess, row.dogrudan_temin_id, row.idare_id);
setDetail.run(JSON.stringify(detail), row.dogrudan_temin_id);
return true;
} catch (err) {
console.warn(`[dt-worker] detay hatası (${row.dogrudan_temin_id}): ${err.message}`);
return false;
}
}),
);
const grupHata = sonuc.filter((x) => !x).length;
ok += sonuc.length - grupHata;
hata += grupHata;
// Adaptif fren: hata varsa yavaşla, temizse hızlan (2.5 sn ile 250 ms arası)
gecikme = grupHata
? Math.min(2500, Math.round(gecikme * 2))
: Math.max(250, Math.round(gecikme * 0.9));
if (i && i % (DETAY_PARALEL * 20) === 0) {
const hiz = (ok / ((Date.now() - basladi) / 1000)).toFixed(1);
console.log(`[dt-worker] ${ok}/${pending.length} detay (${hiz} kayıt/sn, gecikme ${gecikme}ms, hata ${hata})`);
}
await humanDelay();
if (i + DETAY_PARALEL < pending.length) await sleep(gecikme + Math.floor(Math.random() * 200));
}
console.log(`[dt-worker] detay turu: ${ok} başarılı, ${hata} hata, ${Math.round((Date.now() - basladi) / 1000)} sn`);
const total = db.prepare('SELECT COUNT(*) AS c FROM dt_tenders').get().c;
console.log(