fix(routing): avoid full binding rescans in resolveAgentRoute (#36915)

This commit is contained in:
Vignesh Natarajan
2026-03-05 16:49:24 -08:00
parent 1a67cf57e3
commit c260e207b2
3 changed files with 145 additions and 35 deletions

View File

@@ -1,6 +1,7 @@
import { describe, expect, test } from "vitest";
import { describe, expect, test, vi } from "vitest";
import type { ChatType } from "../channels/chat-type.js";
import type { OpenClawConfig } from "../config/config.js";
import * as routingBindings from "./bindings.js";
import { resolveAgentRoute } from "./resolve-route.js";
describe("resolveAgentRoute", () => {
@@ -768,3 +769,43 @@ describe("role-based agent routing", () => {
});
});
});
describe("binding evaluation cache scalability", () => {
test("does not rescan full bindings after channel/account cache rollover (#36915)", () => {
const bindingCount = 2_205;
const cfg: OpenClawConfig = {
bindings: Array.from({ length: bindingCount }, (_, idx) => ({
agentId: `agent-${idx}`,
match: {
channel: "dingtalk",
accountId: `acct-${idx}`,
peer: { kind: "direct", id: `user-${idx}` },
},
})),
};
const listBindingsSpy = vi.spyOn(routingBindings, "listBindings");
try {
for (let idx = 0; idx < bindingCount; idx += 1) {
const route = resolveAgentRoute({
cfg,
channel: "dingtalk",
accountId: `acct-${idx}`,
peer: { kind: "direct", id: `user-${idx}` },
});
expect(route.agentId).toBe(`agent-${idx}`);
expect(route.matchedBy).toBe("binding.peer");
}
const repeated = resolveAgentRoute({
cfg,
channel: "dingtalk",
accountId: "acct-0",
peer: { kind: "direct", id: "user-0" },
});
expect(repeated.agentId).toBe("agent-0");
expect(listBindingsSpy).toHaveBeenCalledTimes(1);
} finally {
listBindingsSpy.mockRestore();
}
});
});