Session 24: Connect everything — Slate wired to all sources, copy fixed, nav fixed, startup prefetch, language button removed (1571 tests)
This commit is contained in:
@@ -4,6 +4,9 @@ const app = require('./app');
|
||||
// otherwise only manifests when the gateway tries to fall over and
|
||||
// finds no chain.
|
||||
const { getConfiguredProviders, listProviderIds } = require('./config/providers');
|
||||
// Session 24 — warm the Tank01 cache after boot so streaks / hot lists /
|
||||
// game lines have data on the first page load. Non-blocking; see module.
|
||||
const { scheduleStartupPrefetch } = require('./startupPrefetch');
|
||||
|
||||
// Default 3001 — Next.js owns 3000 locally and in production. The poller,
|
||||
// internal cron, and BASE_URL conventions all assume 3001 for the Express
|
||||
@@ -18,4 +21,8 @@ app.listen(PORT, () => {
|
||||
if (missing.length) {
|
||||
console.warn(`[VYNDR] providers missing keys: ${missing.join(', ')}`);
|
||||
}
|
||||
|
||||
// Session 24 — fire-and-forget cache warm. 5s delay so Redis is ready.
|
||||
// Skips itself when RAPID_API_KEY is unset; never blocks or crashes boot.
|
||||
scheduleStartupPrefetch();
|
||||
});
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Startup prefetch (Session 24).
|
||||
*
|
||||
* Warms the Tank01 game-log + game-lines cache shortly after the server
|
||||
* boots, so the streaks / hot-list panels and the game-lines strip have
|
||||
* data on the FIRST page load instead of self-hiding until a user
|
||||
* happens to trigger a fetch.
|
||||
*
|
||||
* Hard rules:
|
||||
* - NON-BLOCKING. Server readiness must never wait on this. The caller
|
||||
* schedules it and moves on.
|
||||
* - NEVER crashes the process. Every failure is swallowed + logged.
|
||||
* - Skips entirely when RAPID_API_KEY is absent (nothing to warm, and
|
||||
* no point spinning the prefetch's no-op passes).
|
||||
*
|
||||
* The prefetch module owns its own quota budget (`--max`), so a runaway
|
||||
* can't blow the RapidAPI monthly cap.
|
||||
*/
|
||||
|
||||
const prefetch = require('../scripts/tank01-prefetch');
|
||||
|
||||
const DEFAULTS = Object.freeze({
|
||||
sports: ['nba', 'mlb'],
|
||||
maxRequests: 40, // conservative — bounded by the prefetch's own budget
|
||||
});
|
||||
|
||||
/**
|
||||
* Run the prefetch once. Awaitable for tests; callers in server.js do NOT
|
||||
* await it. Returns the prefetch summary, or null when skipped/failed.
|
||||
*/
|
||||
async function runStartupPrefetch(opts = {}) {
|
||||
const sports = opts.sports || DEFAULTS.sports;
|
||||
const maxRequests = opts.maxRequests || DEFAULTS.maxRequests;
|
||||
|
||||
if (!process.env.RAPID_API_KEY) {
|
||||
console.log('[VYNDR] startup prefetch skipped — RAPID_API_KEY not set');
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
const argv = ['node', 'startup-prefetch', `--sports=${sports.join(',')}`, `--max=${maxRequests}`];
|
||||
const summary = await prefetch.main(argv);
|
||||
console.log('[VYNDR] startup prefetch complete');
|
||||
return summary;
|
||||
} catch (err) {
|
||||
// Swallow — a flaky RapidAPI must never take the API server down.
|
||||
console.warn('[VYNDR] startup prefetch failed:', err.message);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the prefetch to run after `delayMs` (default 5s so Redis is
|
||||
* ready). Returns the timer handle (unref'd so it never keeps the event
|
||||
* loop alive on its own). Fully fire-and-forget.
|
||||
*/
|
||||
function scheduleStartupPrefetch(opts = {}) {
|
||||
const delayMs = opts.delayMs != null ? opts.delayMs : 5000;
|
||||
const timer = setTimeout(() => { void runStartupPrefetch(opts); }, delayMs);
|
||||
if (typeof timer.unref === 'function') timer.unref();
|
||||
return timer;
|
||||
}
|
||||
|
||||
module.exports = { runStartupPrefetch, scheduleStartupPrefetch, DEFAULTS };
|
||||
Reference in New Issue
Block a user