Avoid caching failed scan snapshots
This commit is contained in:
+1
-1
@@ -112,7 +112,7 @@ services:
|
||||
POLYWEATHER_OBSERVATION_COLLECTOR_INITIAL_DELAY_SEC: ${POLYWEATHER_OBSERVATION_COLLECTOR_INITIAL_DELAY_SEC:-5}
|
||||
POLYWEATHER_OBSERVATION_COLLECTOR_MADIS_SEC: ${POLYWEATHER_OBSERVATION_COLLECTOR_MADIS_SEC:-300}
|
||||
POLYWEATHER_OBSERVATION_COLLECTOR_TICK_SEC: ${POLYWEATHER_OBSERVATION_COLLECTOR_TICK_SEC:-30}
|
||||
POLYWEATHER_SCAN_TERMINAL_PREWARM_ENABLED: ${POLYWEATHER_SCAN_TERMINAL_PREWARM_ENABLED:-true}
|
||||
POLYWEATHER_SCAN_TERMINAL_PREWARM_ENABLED: 'true'
|
||||
POLYWEATHER_SERVICE_ROLE: web
|
||||
UVICORN_WORKERS: ${UVICORN_WORKERS:-2}
|
||||
healthcheck:
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { proxyBackendJsonGet } from "@/lib/api-proxy";
|
||||
import { buildForceRefreshProxyCachePolicy } from "@/lib/proxy-cache-policy";
|
||||
import {
|
||||
buildForceRefreshProxyCachePolicy,
|
||||
buildScanTerminalResponseCacheControl,
|
||||
} from "@/lib/proxy-cache-policy";
|
||||
import { DASHBOARD_REFRESH_POLICY_SEC } from "@/lib/refresh-policy";
|
||||
import {
|
||||
createProxyTimer,
|
||||
@@ -64,6 +67,11 @@ export async function GET(req: NextRequest) {
|
||||
try {
|
||||
return await proxyBackendJsonGet(req, {
|
||||
cacheControl: cachePolicy.responseCacheControl,
|
||||
cacheControlForData: (data) =>
|
||||
buildScanTerminalResponseCacheControl(
|
||||
data,
|
||||
cachePolicy.responseCacheControl,
|
||||
),
|
||||
fetchCache:
|
||||
cachePolicy.fetchMode === "no-store" ? "no-store" : undefined,
|
||||
publicMessage: "Failed to fetch scan terminal data",
|
||||
|
||||
@@ -2,6 +2,7 @@ import assert from "node:assert/strict";
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import {
|
||||
buildScanTerminalResponseCacheControl,
|
||||
buildCityDetailProxyCachePolicy,
|
||||
buildForceRefreshProxyCachePolicy,
|
||||
isForceRefreshValue,
|
||||
@@ -26,6 +27,24 @@ export function runTests() {
|
||||
const scanForced = buildForceRefreshProxyCachePolicy("true", 10);
|
||||
assert.equal(scanForced.fetchMode, "no-store");
|
||||
|
||||
const normalScanCache = "public, max-age=0, s-maxage=300, stale-while-revalidate=900";
|
||||
assert.equal(
|
||||
buildScanTerminalResponseCacheControl({ status: "ready", stale: false }, normalScanCache),
|
||||
normalScanCache,
|
||||
);
|
||||
assert.equal(
|
||||
buildScanTerminalResponseCacheControl({ status: "failed", stale: false }, normalScanCache),
|
||||
"no-store, max-age=0",
|
||||
);
|
||||
assert.equal(
|
||||
buildScanTerminalResponseCacheControl({ status: "partial", stale: false }, normalScanCache),
|
||||
"no-store, max-age=0",
|
||||
);
|
||||
assert.equal(
|
||||
buildScanTerminalResponseCacheControl({ status: "ready", stale: true }, normalScanCache),
|
||||
"no-store, max-age=0",
|
||||
);
|
||||
|
||||
const scanTerminalProxySource = fs.readFileSync(
|
||||
path.join(process.cwd(), "app", "api", "scan", "terminal", "route.ts"),
|
||||
"utf8",
|
||||
@@ -40,6 +59,11 @@ export function runTests() {
|
||||
/buildForceRefreshProxyCachePolicy\(forceRefresh,\s*10\)/,
|
||||
"scan terminal proxy must not use the old 10 second edge cache because it over-drives the slow scan endpoint",
|
||||
);
|
||||
assert.match(
|
||||
scanTerminalProxySource,
|
||||
/cacheControlForData:\s*\(data\)\s*=>\s*buildScanTerminalResponseCacheControl/,
|
||||
"scan terminal proxy must not CDN-cache failed, stale, or partial business payloads",
|
||||
);
|
||||
|
||||
const scanTerminalClientSource = fs.readFileSync(
|
||||
path.join(
|
||||
|
||||
@@ -4,6 +4,8 @@ export type ProxyCachePolicy = {
|
||||
revalidateSeconds?: number;
|
||||
};
|
||||
|
||||
const NO_STORE_CACHE_CONTROL = "no-store, max-age=0";
|
||||
|
||||
export function isForceRefreshValue(value: string | null | undefined) {
|
||||
return String(value || "").trim().toLowerCase() === "true";
|
||||
}
|
||||
@@ -15,7 +17,7 @@ export function buildForceRefreshProxyCachePolicy(
|
||||
if (isForceRefreshValue(forceRefresh)) {
|
||||
return {
|
||||
fetchMode: "no-store",
|
||||
responseCacheControl: "no-store, max-age=0",
|
||||
responseCacheControl: NO_STORE_CACHE_CONTROL,
|
||||
};
|
||||
}
|
||||
return {
|
||||
@@ -35,7 +37,7 @@ export function buildCityDetailProxyCachePolicy(
|
||||
if (isForceRefreshValue(forceRefresh)) {
|
||||
return {
|
||||
fetchMode: "no-store",
|
||||
responseCacheControl: "no-store, max-age=0",
|
||||
responseCacheControl: NO_STORE_CACHE_CONTROL,
|
||||
};
|
||||
}
|
||||
return {
|
||||
@@ -47,3 +49,18 @@ export function buildCityDetailProxyCachePolicy(
|
||||
revalidateSeconds,
|
||||
};
|
||||
}
|
||||
|
||||
export function buildScanTerminalResponseCacheControl(
|
||||
data: unknown,
|
||||
readyCacheControl: string,
|
||||
) {
|
||||
if (!data || typeof data !== "object") {
|
||||
return NO_STORE_CACHE_CONTROL;
|
||||
}
|
||||
const payload = data as { stale?: unknown; status?: unknown };
|
||||
const status = String(payload.status || "").trim().toLowerCase();
|
||||
if (payload.stale === true || (status && status !== "ready")) {
|
||||
return NO_STORE_CACHE_CONTROL;
|
||||
}
|
||||
return readyCacheControl;
|
||||
}
|
||||
|
||||
@@ -91,11 +91,7 @@ def test_docker_compose_isolates_collector_from_web_and_bot_services():
|
||||
assert "POLYWEATHER_SERVICE_ROLE: bot" in compose
|
||||
assert "POLYWEATHER_SERVICE_ROLE: collector" in collector_block
|
||||
assert "POLYWEATHER_SCAN_TERMINAL_PREWARM_ENABLED: 'false'" in bot_block
|
||||
assert (
|
||||
"POLYWEATHER_SCAN_TERMINAL_PREWARM_ENABLED: "
|
||||
"${POLYWEATHER_SCAN_TERMINAL_PREWARM_ENABLED:-true}"
|
||||
in web_block
|
||||
)
|
||||
assert "POLYWEATHER_SCAN_TERMINAL_PREWARM_ENABLED: 'true'" in web_block
|
||||
assert "POLYWEATHER_SCAN_TERMINAL_PREWARM_ENABLED: 'false'" in collector_block
|
||||
assert "POLYWEATHER_OBSERVATION_COLLECTOR_ENABLED: 'false'" in bot_block
|
||||
assert "POLYWEATHER_OBSERVATION_COLLECTOR_ENABLED: 'false'" in web_block
|
||||
|
||||
Reference in New Issue
Block a user