fix: 10 dakikada bir havuz 120 kayda düşüyordu
Sorun: önbellek süresi dolunca getTenders cache.tenders'ı ilk partiyle (120 ilan) DEĞİŞTİRİYOR, kalanı arka planda dolduruyordu. Yani her 10 dakikada bir kullanıcı birkaç dakika boyunca eksik liste görüyordu (canlıda 8.258 havuza karşı 5.319 yüklü olarak yakalandı). Çözüm: yenilemede mevcut dolu liste sunulmaya devam ediyor; yeni liste ayrı kurulup TAMAMLANINCA atomik olarak devreye alınıyor. Yalnızca ilk açılışta (elde hiç veri yokken) ilk parti anında gösteriliyor. Doğrulama: zorla yenileme sırasında liste 3.795'te sabit kaldı (öncesinde 120).
This commit is contained in:
+27
-17
@@ -292,11 +292,14 @@ function ilanlariBirlestir(mevcut, yeniAds) {
|
||||
return eklenen;
|
||||
}
|
||||
|
||||
// Kalan sayfaları arka planda çeker; kullanıcı beklemez, havuz zamanla dolar.
|
||||
async function arkaPlandaTamamla(numFound) {
|
||||
// Kalan sayfaları arka planda çeker. Yeni liste ayrı kurulur ve TAMAMLANINCA
|
||||
// atomik olarak devreye alınır; böylece yenileme sırasında kullanıcı hiçbir
|
||||
// zaman eksik listeye düşmez (önceden her yenilemede 120 kayda iniyordu).
|
||||
async function arkaPlandaTamamla(numFound, ilkListe) {
|
||||
if (arkaPlanDoluyor) return;
|
||||
arkaPlanDoluyor = true;
|
||||
try {
|
||||
const yeni = [...ilkListe];
|
||||
const gerekliSayfa = Math.min(MAX_PAGES, Math.ceil(numFound / LIST_SIZE));
|
||||
let page = ILK_PARTI;
|
||||
while (page < gerekliSayfa) {
|
||||
@@ -304,15 +307,17 @@ async function arkaPlandaTamamla(numFound) {
|
||||
const sonuclar = await ilanSayfalari(page, grup);
|
||||
const ads = sonuclar.flatMap((r) => r.ads || []);
|
||||
if (!ads.length) break;
|
||||
const eklenen = ilanlariBirlestir(cache.tenders, ads);
|
||||
if (eklenen.length) cache.tenders = [...cache.tenders, ...eklenen];
|
||||
const eklenen = ilanlariBirlestir(yeni, ads);
|
||||
if (eklenen.length) yeni.push(...eklenen);
|
||||
page += grup;
|
||||
if (page % 60 === 0) {
|
||||
console.log(`[ihaleist-api] arka plan: ${cache.tenders.length}/${numFound} ilan yüklendi`);
|
||||
}
|
||||
await new Promise((r) => setTimeout(r, 120)); // kaynağı yormamak için
|
||||
}
|
||||
console.log(`[ihaleist-api] havuz dolduruldu: ${cache.tenders.length}/${numFound} ilan`);
|
||||
// Yalnızca daha zengin bir liste elde ettiysek devreye al
|
||||
if (yeni.length >= cache.tenders.length) {
|
||||
cache.tenders = yeni;
|
||||
cache.todayCount = yeni.filter((t) => t.isYeni).length;
|
||||
}
|
||||
console.log(`[ihaleist-api] havuz hazır: ${cache.tenders.length}/${numFound} ilan`);
|
||||
} catch (e) {
|
||||
console.warn('[ihaleist-api] arka plan doldurma hatası:', e.message);
|
||||
} finally {
|
||||
@@ -324,24 +329,29 @@ async function getTenders(force = false) {
|
||||
const fresh = cache.tenders && Date.now() - cache.fetchedAt < CACHE_TTL_MS;
|
||||
if (fresh && !force) return cache;
|
||||
|
||||
// İlk parti: paralel, hızlı — kullanıcı bunu bekler
|
||||
const ilk = await ilanSayfalari(0, ILK_PARTI);
|
||||
const numFound = ilk.find((r) => r.numFound)?.numFound || 0;
|
||||
const ads = ilk.flatMap((r) => r.ads || []);
|
||||
|
||||
const seen = new Set();
|
||||
cache.tenders = ads
|
||||
const ilkListe = ads
|
||||
.filter((ad) => (seen.has(ad.id) ? false : seen.add(ad.id)))
|
||||
.map(mapAd);
|
||||
cache.totalCount = numFound || cache.tenders.length;
|
||||
cache.todayCount = cache.tenders.filter((t) => t.isYeni).length;
|
||||
cache.fetchedAt = Date.now();
|
||||
console.log(`[ihaleist-api] ${cache.tenders.length} ihale yüklendi (havuz: ${cache.totalCount}) — kalanı arka planda`);
|
||||
|
||||
// Kalanı arka planda doldur (yanıtı bloklamaz)
|
||||
if (cache.totalCount > cache.tenders.length) {
|
||||
arkaPlandaTamamla(cache.totalCount);
|
||||
cache.totalCount = numFound || ilkListe.length;
|
||||
cache.fetchedAt = Date.now();
|
||||
|
||||
// İlk yükleme: elde hiçbir şey yoksa ilk partiyi hemen göster.
|
||||
// Yenileme: eldeki dolu listeyi KORU, yenisi arka planda hazırlansın.
|
||||
if (!cache.tenders || cache.tenders.length === 0) {
|
||||
cache.tenders = ilkListe;
|
||||
cache.todayCount = ilkListe.filter((t) => t.isYeni).length;
|
||||
console.log(`[ihaleist-api] ilk yükleme: ${ilkListe.length} ilan (havuz ${cache.totalCount}) — kalanı arka planda`);
|
||||
} else {
|
||||
console.log(`[ihaleist-api] yenileme başladı (mevcut ${cache.tenders.length} ilan sunulmaya devam ediyor)`);
|
||||
}
|
||||
|
||||
if (cache.totalCount > ilkListe.length) arkaPlandaTamamla(cache.totalCount, ilkListe);
|
||||
return cache;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user