perf(gateway): optimize sessions/ws/routing

This commit is contained in:
Peter Steinberger
2026-02-14 12:16:26 +00:00
parent c90b3e4d5e
commit 586176730c
5 changed files with 191 additions and 41 deletions

View File

@@ -160,6 +160,57 @@ type BindingScope = {
memberRoleIds: Set<string>;
};
type EvaluatedBindingsCache = {
bindingsRef: OpenClawConfig["bindings"];
byChannelAccount: Map<string, EvaluatedBinding[]>;
};
const evaluatedBindingsCacheByCfg = new WeakMap<OpenClawConfig, EvaluatedBindingsCache>();
const MAX_EVALUATED_BINDINGS_CACHE_KEYS = 2000;
function getEvaluatedBindingsForChannelAccount(
cfg: OpenClawConfig,
channel: string,
accountId: string,
): EvaluatedBinding[] {
const bindingsRef = cfg.bindings;
const existing = evaluatedBindingsCacheByCfg.get(cfg);
const cache =
existing && existing.bindingsRef === bindingsRef
? existing
: { bindingsRef, byChannelAccount: new Map<string, EvaluatedBinding[]>() };
if (cache !== existing) {
evaluatedBindingsCacheByCfg.set(cfg, cache);
}
const cacheKey = `${channel}\t${accountId}`;
const hit = cache.byChannelAccount.get(cacheKey);
if (hit) {
return hit;
}
const evaluated: EvaluatedBinding[] = listBindings(cfg).flatMap((binding) => {
if (!binding || typeof binding !== "object") {
return [];
}
if (!matchesChannel(binding.match, channel)) {
return [];
}
if (!matchesAccountId(binding.match?.accountId, accountId)) {
return [];
}
return [{ binding, match: normalizeBindingMatch(binding.match) }];
});
cache.byChannelAccount.set(cacheKey, evaluated);
if (cache.byChannelAccount.size > MAX_EVALUATED_BINDINGS_CACHE_KEYS) {
cache.byChannelAccount.clear();
cache.byChannelAccount.set(cacheKey, evaluated);
}
return evaluated;
}
function normalizePeerConstraint(
peer: { kind?: string; id?: string } | undefined,
): NormalizedPeerConstraint {
@@ -242,18 +293,7 @@ export function resolveAgentRoute(input: ResolveAgentRouteInput): ResolvedAgentR
const memberRoleIds = input.memberRoleIds ?? [];
const memberRoleIdSet = new Set(memberRoleIds);
const bindings: EvaluatedBinding[] = listBindings(input.cfg).flatMap((binding) => {
if (!binding || typeof binding !== "object") {
return [];
}
if (!matchesChannel(binding.match, channel)) {
return [];
}
if (!matchesAccountId(binding.match?.accountId, accountId)) {
return [];
}
return [{ binding, match: normalizeBindingMatch(binding.match) }];
});
const bindings = getEvaluatedBindingsForChannelAccount(input.cfg, channel, accountId);
const dmScope = input.cfg.session?.dmScope ?? "main";
const identityLinks = input.cfg.session?.identityLinks;