mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-21 10:16:44 +00:00
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:
co-authored by
Claude
Peter Steinberger
parent
8dedb0ebca
commit
a1c16f0a3d
@@ -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();
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user