From d291ce2b9f338cf9ae5b1b50d7c543c5746eeacb Mon Sep 17 00:00:00 2001 From: Fajar Hidayat Date: Thu, 6 Aug 2026 07:44:28 +0700 Subject: [PATCH] fix(sse): evict a principal's own CCR blocks before another principal's (#9146) (#9191) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Validated in local merge-train (devbox-vm-06-dev002) @ combined-tip (FAST gates green: static + changed tests + vitest — only pre-existing audit.test.ts flake). Evidence: /home/diegosouzapw/dev/proxys/OmniRoute/.claude/worktrees/merge-train-20260805-213228-suite.log --- .../services/compression/engines/ccr/index.ts | 39 +++++++-- .../ccr-eviction-scope-9146.test.ts | 79 +++++++++++++++++++ 2 files changed, 110 insertions(+), 8 deletions(-) create mode 100644 tests/unit/compression/ccr-eviction-scope-9146.test.ts diff --git a/open-sse/services/compression/engines/ccr/index.ts b/open-sse/services/compression/engines/ccr/index.ts index 476d9b37b0..245b791e7b 100644 --- a/open-sse/services/compression/engines/ccr/index.ts +++ b/open-sse/services/compression/engines/ccr/index.ts @@ -61,7 +61,12 @@ const RETRIEVAL_THRESHOLD = 3; * ramp (only the >= threshold cliff remains — the legacy binary behavior). */ const RETRIEVAL_RAMP_FACTOR_DEFAULT = 2; -/** Maximum number of entries in the principal-scoped, LRU-ordered store. */ +/** + * Maximum number of entries in the LRU-ordered store, across every principal. The store + * is keyed per principal, but this cap is not: the only per-principal cap is + * `MAX_CCR_PRINCIPAL_BYTES`. Eviction under this cap takes the storing principal's own + * blocks first (see `enforceGlobalBudget`). + */ export const MAX_CCR_ENTRIES = 5_000; export const MAX_CCR_BLOCK_BYTES = 2 * 1024 * 1024; export const MAX_CCR_PRINCIPAL_BYTES = 16 * 1024 * 1024; @@ -257,12 +262,30 @@ function enforcePrincipalBudget(owner: string, bytes: number): boolean { return principalBytes(owner) + bytes <= MAX_CCR_PRINCIPAL_BYTES; } -function enforceGlobalBudget(bytes: number): boolean { - while ( - (ccrStore.size >= MAX_CCR_ENTRIES || ccrTotalBytes + bytes > MAX_CCR_GLOBAL_BYTES) && - evictOldestMatching(() => true) - ) { - // Enforce both entry and global byte caps with LRU eviction. +/** + * Enforce the entry and global byte caps, giving up the storing principal's own + * least-recently-used blocks before anyone else's. + * + * The caps here are global while the only per-principal cap is `MAX_CCR_PRINCIPAL_BYTES`, + * so nothing bounds a principal's entry *count*. Blocks start at `DEFAULT_MIN_CHARS`, so + * 5,000 of them is around 3 MB, under a fifth of one principal's 16 MB byte allowance, + * and enough to exhaust the shared entry budget on its own. Evicting the globally oldest + * entry from there took a block from whoever had been quiet longest, because LRU keeps + * promoting the busy principal's own entries to the tail. + * + * Preferring `owner` keeps the global bound exactly as strict and makes a principal pay + * for its own pressure first. Falling back to any principal preserves the previous + * behaviour for the case that actually needs it: a newcomer storing into a store held + * entirely by others, which would otherwise never fit. + */ +function enforceGlobalBudget(owner: string, bytes: number): boolean { + const overBudget = () => + ccrStore.size >= MAX_CCR_ENTRIES || ccrTotalBytes + bytes > MAX_CCR_GLOBAL_BYTES; + + while (overBudget()) { + if (evictOldestMatching((entry) => entry.principalId === owner)) continue; + if (evictOldestMatching(() => true)) continue; + break; } return ccrTotalBytes + bytes <= MAX_CCR_GLOBAL_BYTES; } @@ -300,7 +323,7 @@ export function tryStoreBlock( return rejectStore(hash, owner, "principal_budget_exceeded"); } - if (!enforceGlobalBudget(bytes)) { + if (!enforceGlobalBudget(owner, bytes)) { return rejectStore(hash, owner, "global_budget_exceeded"); } diff --git a/tests/unit/compression/ccr-eviction-scope-9146.test.ts b/tests/unit/compression/ccr-eviction-scope-9146.test.ts new file mode 100644 index 0000000000..983066b22f --- /dev/null +++ b/tests/unit/compression/ccr-eviction-scope-9146.test.ts @@ -0,0 +1,79 @@ +/** + * #9146. The CCR entry cap is global while the only per-principal cap is bytes, so one + * principal can exhaust the shared 5,000-entry budget with small blocks while staying + * well inside its own 16 MB allowance. Eviction then took the globally oldest block, + * which belongs to whoever has been quiet longest. + */ +import { describe, it, beforeEach } from "node:test"; +import assert from "node:assert/strict"; +import { + MAX_CCR_ENTRIES, + MAX_CCR_PRINCIPAL_BYTES, + inspectCcrBlock, + resetCcrStore, + tryStoreBlock, + getCcrStoreStats, +} from "../../../open-sse/services/compression/engines/ccr/index.ts"; + +/** Distinct content per index, at the engine's minimum block size. */ +function block(seed: number): string { + return `${seed}`.padEnd(600, "x"); +} + +describe("CCR eviction stays inside the storing principal (#9146)", () => { + beforeEach(() => { + resetCcrStore(); + }); + + it("keeps a quiet principal's block when a busy principal fills the entry cap", () => { + const quiet = tryStoreBlock(block(0), "principal-quiet"); + assert.equal(quiet.stored, true); + + // One principal, many small blocks: enough to exhaust the shared entry budget. + for (let i = 1; i <= MAX_CCR_ENTRIES; i++) { + tryStoreBlock(block(i), "principal-busy"); + } + + assert.notEqual( + inspectCcrBlock(quiet.hash, "principal-quiet"), + null, + "a principal that stored one block must not lose it to another principal's traffic" + ); + }); + + it("the busy principal stayed well inside its own byte budget while doing it", () => { + for (let i = 1; i <= MAX_CCR_ENTRIES; i++) { + tryStoreBlock(block(i), "principal-busy"); + } + + const stats = getCcrStoreStats("principal-busy"); + assert.ok( + stats.bytes < MAX_CCR_PRINCIPAL_BYTES / 4, + `expected the busy principal to sit under a quarter of its byte cap, got ${stats.bytes}` + ); + }); + + it("still bounds the store at the entry cap", () => { + for (let i = 0; i <= MAX_CCR_ENTRIES + 50; i++) { + tryStoreBlock(block(i), "principal-busy"); + } + + const stats = getCcrStoreStats("principal-busy"); + assert.ok( + stats.entries <= MAX_CCR_ENTRIES, + `entry cap must still hold, got ${stats.entries}` + ); + }); + + it("falls back to another principal's blocks when the storing one has none", () => { + // A store held entirely by someone else must still admit a newcomer, or a full cache + // would permanently lock out every principal that arrives late. + for (let i = 0; i < MAX_CCR_ENTRIES; i++) { + tryStoreBlock(block(i), "principal-incumbent"); + } + + const newcomer = tryStoreBlock(block(MAX_CCR_ENTRIES + 1), "principal-newcomer"); + assert.equal(newcomer.stored, true); + assert.notEqual(inspectCcrBlock(newcomer.hash, "principal-newcomer"), null); + }); +});