goals
This commit is contained in:
40
lib/feeds.ts
40
lib/feeds.ts
@@ -670,18 +670,11 @@ function normMinuteStr(min: string | null | undefined): string {
|
||||
return (min ?? "").replace(/'/g, "").replace(/\s+/g, "").trim();
|
||||
}
|
||||
|
||||
const RECENT_FINISHED_MS = 60 * 60 * 1000; // 60 Minuten
|
||||
const MATCH_DURATION_ESTIMATE = 2.5 * 60 * 60 * 1000; // 2.5h Puffer für Spiel + Pause + Nachspielzeit
|
||||
|
||||
function isRecentlyFinished(m: Match): boolean {
|
||||
if (m.status !== "FINISHED") return false;
|
||||
const kickoff = new Date(m.utcDate).getTime();
|
||||
if (isNaN(kickoff)) return false;
|
||||
return kickoff + MATCH_DURATION_ESTIMATE > Date.now() - RECENT_FINISHED_MS;
|
||||
}
|
||||
|
||||
async function fetchFifaGoals(idStage: string, idMatch: string, locale: string = "de"): Promise<FifaGoalRaw[]> {
|
||||
return cached(`fifa:detail:${locale}:${idMatch}`, 60_000, async () => {
|
||||
async function fetchFifaGoals(
|
||||
idStage: string, idMatch: string, locale: string = "de",
|
||||
ttlMs: number = 60_000,
|
||||
): Promise<FifaGoalRaw[]> {
|
||||
return cached(`fifa:detail:${locale}:${idMatch}`, ttlMs, async () => {
|
||||
const lang = locale === "en" ? "en" : "de";
|
||||
const url = `${FIFA_BASE}/live/football/17/${FIFA_SEASON}/${idStage}/${idMatch}?language=${lang}`;
|
||||
const res = await fetch(url, {
|
||||
@@ -724,16 +717,16 @@ async function fetchFifaGoals(idStage: string, idMatch: string, locale: string =
|
||||
});
|
||||
}
|
||||
|
||||
// Lädt Tor-Details für laufende oder kürzlich beendete Spiele mit Toren.
|
||||
// FINISHED-Matches werden nur innerhalb eines 60-Minuten-Fensters berücksichtigt,
|
||||
// um die Request-Zahl bei 79+ Spielen im Turnierverlauf drastisch zu reduzieren.
|
||||
// Lädt Tor-Details für laufende und alle beendeten Spiele mit Toren.
|
||||
// Beendete Spiele werden über langlebiges Caching (24h) gespart, nicht über Ausschluss.
|
||||
// Tore eines beendeten Spiels ändern sich nie mehr → einmal fetchen genügt.
|
||||
export async function attachFifaGoals(
|
||||
matches: Match[],
|
||||
fifaData: { scores: Map<number, FifaScores>; fifaIdToAppCode: Map<string, string> },
|
||||
locale: string = "de",
|
||||
): Promise<Match[]> {
|
||||
const targets = matches.filter(m =>
|
||||
((m.status === "LIVE" || m.status === "IN_PLAY" || m.status === "PAUSED") || isRecentlyFinished(m)) &&
|
||||
(m.status === "LIVE" || m.status === "IN_PLAY" || m.status === "PAUSED" || m.status === "FINISHED") &&
|
||||
((m.homeScore ?? 0) + (m.awayScore ?? 0)) > 0,
|
||||
);
|
||||
if (targets.length === 0) return matches;
|
||||
@@ -742,7 +735,9 @@ export async function attachFifaGoals(
|
||||
const results = await Promise.allSettled(targets.map(async (m) => {
|
||||
const fs = fifaData.scores.get(m.matchNumber);
|
||||
if (!fs?.idMatch || !fs?.idStage) return;
|
||||
const goals = await fetchFifaGoals(fs.idStage, fs.idMatch, locale);
|
||||
const isFinished = m.status === "FINISHED";
|
||||
const ttl = isFinished ? 24 * 60 * 60 * 1000 : 60_000;
|
||||
const goals = await fetchFifaGoals(fs.idStage, fs.idMatch, locale, ttl);
|
||||
if (goals.length) goalsByMatchId.set(m.id, goals);
|
||||
}));
|
||||
|
||||
@@ -787,11 +782,14 @@ export async function attachFifaLiveData(
|
||||
// --- Step 2: Scores auf Matches anwenden ---
|
||||
const updated = applyFifaScores(matches, teams, fifaData);
|
||||
|
||||
// --- Step 3: Goal-Details nur für live + kürzlich beendete Matches mit Toren ---
|
||||
// --- Step 3: Goal-Details für alle Spiele mit Toren (live + beendet) ---
|
||||
// Requests werden durch differenzierte Cache-TTL gespart:
|
||||
// beendete Spiele → 24h (Tore ändern sich nie)
|
||||
// laufende Spiele → 60s (neue Tore erscheinen)
|
||||
const targets = updated.filter(m => {
|
||||
const fs = fifaData.scores.get(m.matchNumber);
|
||||
return (
|
||||
((m.status === "LIVE" || m.status === "IN_PLAY" || m.status === "PAUSED") || isRecentlyFinished(m)) &&
|
||||
(m.status === "LIVE" || m.status === "IN_PLAY" || m.status === "PAUSED" || m.status === "FINISHED") &&
|
||||
((m.homeScore ?? 0) + (m.awayScore ?? 0)) > 0 &&
|
||||
fs?.idMatch != null &&
|
||||
fs?.idStage != null
|
||||
@@ -810,8 +808,10 @@ export async function attachFifaLiveData(
|
||||
for (const m of targets) {
|
||||
const fs = fifaData.scores.get(m.matchNumber)!;
|
||||
if (!fs.idMatch || !fs.idStage) continue;
|
||||
const isFinished = m.status === "FINISHED";
|
||||
const ttl = isFinished ? 24 * 60 * 60 * 1000 : 60_000; // beendet: 24h, live: 60s
|
||||
try {
|
||||
const goals = await fetchFifaGoals(fs.idStage, fs.idMatch, locale);
|
||||
const goals = await fetchFifaGoals(fs.idStage, fs.idMatch, locale, ttl);
|
||||
fetched++;
|
||||
if (goals.length) goalsByMatchId.set(m.id, goals);
|
||||
} catch {
|
||||
|
||||
Reference in New Issue
Block a user