Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion messages/en/settings/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@
"enforce": "Enabled"
},
"replayEnabled": "Request Replay",
"replayEnabledDesc": "Caches upstream responses and reuses upstream connections: identical concurrent or reconnecting requests attach to the in-flight stream instead of re-hitting the provider. Follows the ENABLE_REQUEST_REPLAY environment variable until saved here. Default off.",
"replayEnabledDesc": "Caches upstream responses and reuses upstream connections: identical concurrent or reconnecting requests attach to the in-flight stream instead of re-hitting the provider. Follows the ENABLE_REQUEST_REPLAY environment variable until saved here. Default on.",
"cacheEffectivenessEnabled": "Prefix Cache Simulation",
"cacheEffectivenessEnabledDesc": "Simulates longest-prefix cache hit rates (theoretical vs actual) for observability only; never affects routing. Follows the ENABLE_CACHE_EFFECTIVENESS environment variable until saved here. Default on."
},
Expand Down
2 changes: 1 addition & 1 deletion messages/ja/settings/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@
"enforce": "有効"
},
"replayEnabled": "リクエスト Replay",
"replayEnabledDesc": "上流レスポンスをキャッシュし上流接続を再利用します。同一リクエストの並行実行や再接続は進行中のストリームに追随し、プロバイダーへ再送しません。保存するまでは環境変数 ENABLE_REQUEST_REPLAY に従います。デフォルトはオフ。",
"replayEnabledDesc": "上流レスポンスをキャッシュし上流接続を再利用します。同一リクエストの並行実行や再接続は進行中のストリームに追随し、プロバイダーへ再送しません。保存するまでは環境変数 ENABLE_REQUEST_REPLAY に従います。デフォルトはオン。",
"cacheEffectivenessEnabled": "プレフィックスキャッシュシミュレーション",
"cacheEffectivenessEnabledDesc": "最長プレフィックス一致のキャッシュヒット率(理論値 vs 実測値)を観測目的でシミュレートします。ルーティングには影響しません。保存するまでは環境変数 ENABLE_CACHE_EFFECTIVENESS に従います。デフォルトはオン。"
},
Expand Down
2 changes: 1 addition & 1 deletion messages/ru/settings/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@
"enforce": "Включено"
},
"replayEnabled": "Replay запросов",
"replayEnabledDesc": "Кэширует ответы провайдера и переиспользует соединения: одинаковые параллельные или переподключающиеся запросы присоединяются к текущему потоку вместо повторного обращения к провайдеру. До сохранения следует переменной окружения ENABLE_REQUEST_REPLAY. По умолчанию выключено.",
"replayEnabledDesc": "Кэширует ответы провайдера и переиспользует соединения: одинаковые параллельные или переподключающиеся запросы присоединяются к текущему потоку вместо повторного обращения к провайдеру. До сохранения следует переменной окружения ENABLE_REQUEST_REPLAY. По умолчанию включено.",
"cacheEffectivenessEnabled": "Симуляция префиксного кэша",
"cacheEffectivenessEnabledDesc": "Симулирует хит-рейт кэша по наибольшему префиксу (теория и факт) только для наблюдаемости; не влияет на маршрутизацию. До сохранения следует переменной окружения ENABLE_CACHE_EFFECTIVENESS. По умолчанию включено."
},
Expand Down
2 changes: 1 addition & 1 deletion messages/zh-CN/settings/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@
"enforce": "启用"
},
"replayEnabled": "请求 Replay",
"replayEnabledDesc": "缓存上游响应并复用上游连接:并发或断线重连的相同请求直接跟尾在途流,不再重复请求供应商。保存前跟随环境变量 ENABLE_REQUEST_REPLAY,默认关闭。",
"replayEnabledDesc": "缓存上游响应并复用上游连接:并发或断线重连的相同请求直接跟尾在途流,不再重复请求供应商。保存前跟随环境变量 ENABLE_REQUEST_REPLAY,默认开启。",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

统一中文 Replay 描述的措辞。

两种中文翻译都使用了“跟尾在途流/串流”。该表达不够自然,可能使用户无法明确理解请求会加入现有的 in-flight stream。

  • messages/zh-CN/settings/config.json#L98-L98:将“直接跟尾在途流”改为“直接加入在途流”,并使用中文标点。
  • messages/zh-TW/settings/config.json#L174-L174:将“直接跟尾在途串流”改为“直接加入進行中的串流”,并使用中文标点。
📍 Affects 2 files
  • messages/zh-CN/settings/config.json#L98-L98 (this comment)
  • messages/zh-TW/settings/config.json#L174-L174
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@messages/zh-CN/settings/config.json` at line 98, 统一 Replay 描述措辞:在
messages/zh-CN/settings/config.json 第98行,将“直接跟尾在途流”改为“直接加入在途流”并使用中文标点;在
messages/zh-TW/settings/config.json 第174行,将“直接跟尾在途串流”改为“直接加入進行中的串流”并使用中文标点。

"cacheEffectivenessEnabled": "前缀缓存模拟",
"cacheEffectivenessEnabledDesc": "模拟最长前缀匹配的缓存命中率(理论 vs 实际),仅用于观测,不影响路由。保存前跟随环境变量 ENABLE_CACHE_EFFECTIVENESS,默认开启。",
"affinityIgnoreClientSessionId": "忽略客户端 Session ID",
Expand Down
2 changes: 1 addition & 1 deletion messages/zh-TW/settings/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@
"enforce": "啟用"
},
"replayEnabled": "請求 Replay",
"replayEnabledDesc": "快取上游回應並重用上游連線:並發或斷線重連的相同請求直接跟尾在途串流,不再重複請求供應商。儲存前跟隨環境變數 ENABLE_REQUEST_REPLAY,預設關閉。",
"replayEnabledDesc": "快取上游回應並重用上游連線:並發或斷線重連的相同請求直接跟尾在途串流,不再重複請求供應商。儲存前跟隨環境變數 ENABLE_REQUEST_REPLAY,預設開啟。",
"cacheEffectivenessEnabled": "前綴快取模擬",
"cacheEffectivenessEnabledDesc": "模擬最長前綴匹配的快取命中率(理論 vs 實際),僅用於觀測,不影響路由。儲存前跟隨環境變數 ENABLE_CACHE_EFFECTIVENESS,預設開啟。"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ import type {
interface SystemSettingsFormProps {
/** Read-only runtime value; SESSION_TTL is not a persisted system setting. */
sessionTtlSeconds?: number;
/** Read-only env fallback used while replayEnabled remains null. */
replayDefaultEnabled?: boolean;
initialSettings: Pick<
SystemSettings,
| "siteTitle"
Expand Down Expand Up @@ -131,6 +133,7 @@ type DiscoveryNumberValue = number | "";
export function SystemSettingsForm({
initialSettings,
sessionTtlSeconds = 300,
replayDefaultEnabled = true,
}: SystemSettingsFormProps) {
const router = useRouter();
const t = useTranslations("settings.config.form");
Expand Down Expand Up @@ -214,7 +217,7 @@ export function SystemSettingsForm({
const [affinityIgnoreClientSessionId, setAffinityIgnoreClientSessionId] = useState(
initialSettings.affinityIgnoreClientSessionId
);
// null = 跟随环境变量(Replay 默认关 / 缓存模拟默认开):未触碰开关时按 null 原样保存,
// null = 跟随环境变量:未触碰开关时按 null 原样保存,
// 避免无关字段的保存把覆写写死为布尔值;仅用户切换后才落显式值
const [replayEnabled, setReplayEnabled] = useState<boolean | null>(initialSettings.replayEnabled);
const [cacheEffectivenessEnabled, setCacheEffectivenessEnabled] = useState<boolean | null>(
Expand Down Expand Up @@ -1187,7 +1190,7 @@ export function SystemSettingsForm({
<Switch
id="replay-enabled"
aria-label={t("replayEnabled")}
checked={replayEnabled ?? false}
checked={replayEnabled ?? replayDefaultEnabled}
onCheckedChange={(checked) => setReplayEnabled(checked)}
disabled={isPending}
/>
Expand Down
4 changes: 3 additions & 1 deletion src/app/[locale]/settings/config/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ export default async function SettingsConfigPage({
async function SettingsConfigContent({ locale }: { locale: string }) {
const t = await getTranslations({ locale, namespace: "settings" });
const settings = await getSystemSettings();
const sessionTtlSeconds = Math.max(1, Math.floor(getEnvConfig().SESSION_TTL));
const env = getEnvConfig();
const sessionTtlSeconds = Math.max(1, Math.floor(env.SESSION_TTL));

return (
<>
Expand All @@ -47,6 +48,7 @@ async function SettingsConfigContent({ locale }: { locale: string }) {
>
<SystemSettingsForm
sessionTtlSeconds={sessionTtlSeconds}
replayDefaultEnabled={env.ENABLE_REQUEST_REPLAY}
initialSettings={{
siteTitle: settings.siteTitle,
allowGlobalUsageView: settings.allowGlobalUsageView,
Expand Down
2 changes: 1 addition & 1 deletion src/lib/config/env.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ export const EnvSchema = z.object({
.max(64 * 1024 * 1024)
.default(10 * 1024 * 1024),
// 请求分离 + Replay:客户端断开后上游继续引流缓存,相同请求体重发续传
ENABLE_REQUEST_REPLAY: z.string().default("false").transform(booleanTransform),
ENABLE_REQUEST_REPLAY: z.string().default("true").transform(booleanTransform),
// owner 客户端仍在线时的并发相同请求去重(attached-live);关闭后仅 detached/completed 可命中
REPLAY_LIVE_DEDUP_ENABLED: z.string().default("true").transform(booleanTransform),
// 客户端断开后上游继续引流的最长时长(毫秒;替代默认 60s drain 上限)
Expand Down
2 changes: 1 addition & 1 deletion src/types/system-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ export interface SystemSettings {
affinityIgnoreClientSessionId: boolean;

// F2 Replay(响应缓存与上游连接复用)开关覆写
// null = 跟随环境变量 ENABLE_REQUEST_REPLAY(默认 false
// null = 跟随环境变量 ENABLE_REQUEST_REPLAY(默认 true
replayEnabled: boolean | null;

// F3b 最长前缀匹配缓存模拟(理论 vs 实际缓存命中率,仅观测不影响路由)开关覆写
Expand Down
15 changes: 15 additions & 0 deletions tests/unit/lib/env-request-replay.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { describe, expect, test } from "vitest";
import { EnvSchema } from "@/lib/config/env.schema";

describe("EnvSchema - ENABLE_REQUEST_REPLAY", () => {
test("defaults to enabled when unset", () => {
expect(EnvSchema.parse({}).ENABLE_REQUEST_REPLAY).toBe(true);
});

test.each([
["true", true],
["false", false],
] as const)("preserves an explicit %s value", (value, expected) => {
expect(EnvSchema.parse({ ENABLE_REQUEST_REPLAY: value }).ENABLE_REQUEST_REPLAY).toBe(expected);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,11 @@ describe("SystemSettingsForm replay/cache-effectiveness null 三态", () => {
});

test("未触碰开关时保存保持 null(跟随环境变量),不写死布尔覆写", async () => {
const { unmount } = render(<SystemSettingsForm initialSettings={baseSettings} />);
const { unmount } = render(
<SystemSettingsForm initialSettings={baseSettings} replayDefaultEnabled={true} />
);

expect(document.getElementById("replay-enabled")?.getAttribute("aria-checked")).toBe("true");

await submitForm();

Expand All @@ -170,7 +174,9 @@ describe("SystemSettingsForm replay/cache-effectiveness null 三态", () => {
});

test("用户切换开关后保存为显式覆写,未动的另一开关仍为 null", async () => {
const { unmount } = render(<SystemSettingsForm initialSettings={baseSettings} />);
const { unmount } = render(
<SystemSettingsForm initialSettings={baseSettings} replayDefaultEnabled={true} />
);

const switchEl = document.getElementById("replay-enabled");
if (!switchEl) throw new Error("未找到 replay-enabled 开关");
Expand All @@ -183,11 +189,21 @@ describe("SystemSettingsForm replay/cache-effectiveness null 三态", () => {

expect(systemConfigActionMocks.saveSystemSettings).toHaveBeenCalledWith(
expect.objectContaining({
replayEnabled: true,
replayEnabled: false,
cacheEffectivenessEnabled: null,
})
);

unmount();
});

test("环境变量显式关闭时,null 覆写显示为关闭", () => {
const { unmount } = render(
<SystemSettingsForm initialSettings={baseSettings} replayDefaultEnabled={false} />
);

expect(document.getElementById("replay-enabled")?.getAttribute("aria-checked")).toBe("false");

unmount();
});
});
Loading