/** * Планировщик пинга сервисов из списка настроек. * Периодически вызывает refreshPingServicesCache и обновляет кеш для GET /api/ping-services. */ const { readS3TextObject } = require('./s3Service'); const { refreshPingServicesCache } = require('../routes/miscRoutes'); const UI_SETTINGS_KEY = 'bgp_data/rt_ui_settings.json'; const DEFAULT_INTERVAL_MINUTES = 2; let schedulerTimer = null; let lastScheduledRunAt = null; function getSettingsFromUiSettings(uiSettings) { return { enabled: uiSettings.pingServicesSchedulerEnabled !== false, intervalMinutes: Math.max(1, Math.min(1440, parseInt(uiSettings.pingServicesSchedulerIntervalMinutes, 10) || DEFAULT_INTERVAL_MINUTES)), }; } /** * Время следующего запуска по расписанию (timestamp или null если выключено). */ function getNextRunAt(settings) { if (!settings || !settings.enabled) return null; const intervalMs = (settings.intervalMinutes || DEFAULT_INTERVAL_MINUTES) * 60 * 1000; const from = lastScheduledRunAt || Date.now(); return from + intervalMs; } /** * Запустить планировщик пинг-сервисов. * @param {object} logger - pino logger */ function initPingServicesScheduler(logger) { const log = logger || console; async function tick() { lastScheduledRunAt = Date.now(); let uiSettings; try { const raw = await readS3TextObject(UI_SETTINGS_KEY).catch(() => ({ body: '{}' })); uiSettings = JSON.parse(raw?.body || '{}') || {}; } catch (_) { return; } const settings = getSettingsFromUiSettings(uiSettings); if (!settings.enabled) return; log.info({ component: 'ping-services-scheduler' }, 'Running ping services refresh'); refreshPingServicesCache().catch((err) => { log.error({ component: 'ping-services-scheduler', err: err?.message }, 'Ping services refresh failed'); }); } async function schedule() { let uiSettings; try { const raw = await readS3TextObject(UI_SETTINGS_KEY).catch(() => ({ body: '{}' })); uiSettings = JSON.parse(raw?.body || '{}') || {}; } catch (_) { return; } const settings = getSettingsFromUiSettings(uiSettings); if (!settings.enabled) { log.info({ component: 'ping-services-scheduler' }, 'Ping services scheduler disabled in settings'); return; } const intervalMs = settings.intervalMinutes * 60 * 1000; log.info( { component: 'ping-services-scheduler', intervalMinutes: settings.intervalMinutes }, 'Ping services scheduler started (first run in 15 s, then every %d min)', settings.intervalMinutes ); schedulerTimer = setInterval(tick, intervalMs); setTimeout(() => tick(), 15 * 1000); } schedule(); } function stopPingServicesScheduler() { if (schedulerTimer) { clearInterval(schedulerTimer); schedulerTimer = null; } } module.exports = { initPingServicesScheduler, stopPingServicesScheduler, getSettingsFromUiSettings, getNextRunAt, };