fix(usage-bar): cap warnedTemplateOverrides warn-once dedupe cache (#102659)

* fix(usage-bar): cap warnedTemplateOverrides warn-once dedupe cache

Replace unbounded warnedTemplateOverrides Set with createDedupeCache(maxSize=256)
for consistency with the bounded fileCache Map (MAX_CACHED_TEMPLATE_FILES=64)
already present in the same file.

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(usage-bar): bound invalid-template warnings

Co-authored-by: ZengWen-DT <ceng.wen@xydigit.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
This commit is contained in:
Wynne668
2026-07-09 22:29:12 +01:00
committed by GitHub
co-authored by Claude Peter Steinberger
parent 8dedb0ebca
commit a1c16f0a3d
2 changed files with 39 additions and 3 deletions
+30
View File
@@ -113,6 +113,36 @@ describe("loadUsageBarTemplate", () => {
expect(loadUsageBarTemplate(path)).toMatchObject(tplB);
});
it("bounds invalid-template warnings by least-recently-used path", () => {
const dir = tmpDir();
const paths = Array.from({ length: 257 }, (_, index) => {
const path = join(dir, `bad-${index}.json`);
writeFileSync(path, "{ not json");
return path;
});
for (const path of paths.slice(0, 256)) {
expect(loadUsageBarTemplate(path)).toBe(DEFAULT_USAGE_BAR_TEMPLATE);
}
expect(warnSpy).toHaveBeenCalledTimes(256);
// Refresh the oldest warning before overflow so the next key becomes the LRU victim.
expect(loadUsageBarTemplate(paths[0])).toBe(DEFAULT_USAGE_BAR_TEMPLATE);
expect(warnSpy).toHaveBeenCalledTimes(256);
expect(loadUsageBarTemplate(paths[256])).toBe(DEFAULT_USAGE_BAR_TEMPLATE);
expect(warnSpy).toHaveBeenCalledTimes(257);
expect(loadUsageBarTemplate(paths[0])).toBe(DEFAULT_USAGE_BAR_TEMPLATE);
expect(warnSpy).toHaveBeenCalledTimes(257);
expect(loadUsageBarTemplate(paths[1])).toBe(DEFAULT_USAGE_BAR_TEMPLATE);
expect(warnSpy).toHaveBeenCalledTimes(258);
expect(warnSpy).toHaveBeenLastCalledWith(
"configured usage template could not be used; using built-in footer",
{ source: "file", reason: "invalid-json", path: paths[1] },
);
});
describe("cache eviction", () => {
it("evicts the oldest entry and closes its watcher when inserting a new key over the limit", () => {
const dir = tmpDir();
+9 -3
View File
@@ -1,6 +1,7 @@
import { type FSWatcher, readFileSync, watch } from "node:fs";
import { homedir } from "node:os";
import { isAbsolute, resolve } from "node:path";
import { createDedupeCache } from "../../infra/dedupe.js";
import { createSubsystemLogger } from "../../logging/subsystem.js";
import { DEFAULT_USAGE_BAR_TEMPLATE } from "./default-template.js";
import type { UsageBarTemplate } from "./translator.js";
@@ -11,7 +12,13 @@ type CacheEntry = { template: UsageBarTemplate | undefined; watcher?: FSWatcher
const fileCache = new Map<string, CacheEntry>();
/** Maximum number of template file paths to cache concurrently. */
const MAX_CACHED_TEMPLATE_FILES = 64;
const warnedTemplateOverrides = new Set<string>();
const MAX_WARNED_TEMPLATE_OVERRIDES = 256;
// Retain recent warning keys without accumulating every historical config value.
// LRU eviction intentionally allows old invalid overrides to warn again.
const warnedTemplateOverrides = createDedupeCache({
maxSize: MAX_WARNED_TEMPLATE_OVERRIDES,
ttlMs: 0,
});
const usageTemplateLog = createSubsystemLogger("usage-template");
function expandPath(p: string): string {
@@ -87,10 +94,9 @@ function getErrorCode(error: unknown): string | undefined {
function warnInvalidUsageTemplate(source: "inline" | "file", reason: string, path?: string): void {
const key = `${source}:${reason}:${path ?? ""}`;
if (warnedTemplateOverrides.has(key)) {
if (warnedTemplateOverrides.check(key)) {
return;
}
warnedTemplateOverrides.add(key);
usageTemplateLog.warn("configured usage template could not be used; using built-in footer", {
source,
reason,