From a8a5460bf24966d74ebbcacbdd5ad9ba75f78325 Mon Sep 17 00:00:00 2001 From: VrianCao <45995071+VrianCao@users.noreply.github.com> Date: Tue, 14 Apr 2026 10:58:17 +0000 Subject: [PATCH] perf(scheduler): refresh homepage snapshot inline --- apps/worker/src/scheduler/scheduled.ts | 44 ++++---------------------- apps/worker/test/scheduled.test.ts | 37 +++++----------------- 2 files changed, 15 insertions(+), 66 deletions(-) diff --git a/apps/worker/src/scheduler/scheduled.ts b/apps/worker/src/scheduler/scheduled.ts index b940899..9f0a250 100644 --- a/apps/worker/src/scheduler/scheduled.ts +++ b/apps/worker/src/scheduler/scheduled.ts @@ -33,37 +33,14 @@ const PERSIST_BATCH_SIZE = 25; // Look back a bit so maintenance start/end notifications are not missed if a tick is delayed. const MAINTENANCE_EVENT_LOOKBACK_SECONDS = 10 * 60; -async function refreshHomepageSnapshotViaService(env: Env): Promise { - if (!env.SELF) { - throw new Error('SELF service binding missing'); - } - if (!env.ADMIN_TOKEN) { - throw new Error('ADMIN_TOKEN missing'); - } - - const res = await env.SELF.fetch( - new Request('http://internal/api/v1/internal/refresh/homepage', { - method: 'POST', - headers: { - 'Content-Type': 'text/plain; charset=utf-8', - }, - body: env.ADMIN_TOKEN, - }), - ); - - if (!res.ok) { - const text = await res.text().catch(() => ''); - throw new Error(`service refresh failed: HTTP ${res.status} ${text}`.trim()); - } -} - async function refreshHomepageSnapshotInline(env: Env, now: number): Promise { - const [{ computePublicHomepagePayload }, { refreshPublicHomepageSnapshot }] = await Promise.all([ + const [{ computePublicHomepagePayload }, { refreshPublicHomepageSnapshotIfNeeded }] = + await Promise.all([ import('../public/homepage'), - import('../snapshots'), + import('../snapshots/public-homepage'), ]); - await refreshPublicHomepageSnapshot({ + await refreshPublicHomepageSnapshotIfNeeded({ db: env.DB, now, compute: () => computePublicHomepagePayload(env.DB, now), @@ -705,16 +682,9 @@ export async function runScheduledTick(env: Env, ctx: ExecutionContext): Promise const now = Math.floor(Date.now() / 1000); const checkedAt = Math.floor(now / 60) * 60; const queueHomepageRefresh = () => - env.SELF - ? refreshHomepageSnapshotViaService(env).catch(async (err) => { - console.warn('homepage snapshot: service refresh failed', err); - await refreshHomepageSnapshotInline(env, now).catch((fallbackErr) => { - console.warn('homepage snapshot: refresh failed', fallbackErr); - }); - }) - : refreshHomepageSnapshotInline(env, now).catch((err) => { - console.warn('homepage snapshot: refresh failed', err); - }); + refreshHomepageSnapshotInline(env, now).catch((err) => { + console.warn('homepage snapshot: refresh failed', err); + }); const acquired = await acquireLease(env.DB, LOCK_NAME, now, LOCK_LEASE_SECONDS); if (!acquired) { diff --git a/apps/worker/test/scheduled.test.ts b/apps/worker/test/scheduled.test.ts index d082583..4fea227 100644 --- a/apps/worker/test/scheduled.test.ts +++ b/apps/worker/test/scheduled.test.ts @@ -18,8 +18,8 @@ vi.mock('../src/notify/webhook', () => ({ vi.mock('../src/public/homepage', () => ({ computePublicHomepagePayload: vi.fn(), })); -vi.mock('../src/snapshots', () => ({ - refreshPublicHomepageSnapshot: vi.fn(), +vi.mock('../src/snapshots/public-homepage', () => ({ + refreshPublicHomepageSnapshotIfNeeded: vi.fn(), })); import type { Env } from '../src/env'; @@ -29,7 +29,7 @@ import { dispatchWebhookToChannels } from '../src/notify/webhook'; import { computePublicHomepagePayload } from '../src/public/homepage'; import { runScheduledTick } from '../src/scheduler/scheduled'; import { acquireLease } from '../src/scheduler/lock'; -import { refreshPublicHomepageSnapshot } from '../src/snapshots'; +import { refreshPublicHomepageSnapshotIfNeeded } from '../src/snapshots/public-homepage'; import { readSettings } from '../src/settings'; import { createFakeD1Database, type FakeD1QueryHandler } from './helpers/fake-d1'; @@ -160,7 +160,7 @@ describe('scheduler/scheduled regression', () => { resolved_incident_preview: null, maintenance_history_preview: null, } as never); - vi.mocked(refreshPublicHomepageSnapshot).mockResolvedValue(undefined); + vi.mocked(refreshPublicHomepageSnapshotIfNeeded).mockResolvedValue(false); vi.mocked(runHttpCheck).mockResolvedValue({ status: 'up', latencyMs: 21, @@ -205,40 +205,19 @@ describe('scheduler/scheduled regression', () => { expect(readSettings).toHaveBeenCalledTimes(1); expect(waitUntil).toHaveBeenCalledTimes(1); await Promise.all(waitUntil.mock.calls.map((call) => call[0] as Promise)); - expect(refreshPublicHomepageSnapshot).toHaveBeenCalledWith({ + expect(refreshPublicHomepageSnapshotIfNeeded).toHaveBeenCalledWith({ db: env.DB, now: expectedNow, compute: expect.any(Function), }); - const refreshArgs = vi.mocked(refreshPublicHomepageSnapshot).mock.calls[0]?.[0]; + const refreshArgs = vi.mocked(refreshPublicHomepageSnapshotIfNeeded).mock.calls[0]?.[0]; expect(refreshArgs).toBeDefined(); await refreshArgs?.compute(); expect(computePublicHomepagePayload).toHaveBeenCalledWith(env.DB, expectedNow); }); - it('self-invokes homepage refresh via service binding when SELF is configured', async () => { - const env = createEnv({ dueRows: [] }) as unknown as Env; - env.ADMIN_TOKEN = 'test-admin-token'; - const selfFetch = vi.fn().mockResolvedValueOnce(new Response('ok', { status: 200 })); - env.SELF = { fetch: selfFetch } as unknown as Fetcher; - const waitUntil = vi.fn(); - - await runScheduledTick(env, { waitUntil } as unknown as ExecutionContext); - - expect(waitUntil).toHaveBeenCalledTimes(1); - await Promise.all(waitUntil.mock.calls.map((call) => call[0] as Promise)); - - expect(selfFetch).toHaveBeenCalledTimes(1); - const req = selfFetch.mock.calls[0]?.[0] as Request; - expect(req).toBeInstanceOf(Request); - expect(req.method).toBe('POST'); - expect(new URL(req.url).pathname).toBe('/api/v1/internal/refresh/homepage'); - expect(await req.text()).toBe('test-admin-token'); - expect(refreshPublicHomepageSnapshot).not.toHaveBeenCalled(); - }); - it('logs homepage snapshot refresh failures without breaking the tick', async () => { - vi.mocked(refreshPublicHomepageSnapshot).mockRejectedValueOnce( + vi.mocked(refreshPublicHomepageSnapshotIfNeeded).mockRejectedValueOnce( new Error('snapshot refresh failed'), ); @@ -333,7 +312,7 @@ describe('scheduler/scheduled regression', () => { expect(waitUntil).toHaveBeenCalledTimes(1); await Promise.all(waitUntil.mock.calls.map((call) => call[0] as Promise)); - expect(refreshPublicHomepageSnapshot).toHaveBeenCalledTimes(1); + expect(refreshPublicHomepageSnapshotIfNeeded).toHaveBeenCalledTimes(1); }); it('passes explicit response assertion modes through scheduled HTTP checks', async () => {