perf(slack): cache stream recipient team lookup

(cherry picked from commit 8ce7cc8aae)
This commit is contained in:
Vincent Koc
2026-05-03 10:35:10 -07:00
parent c0302512d4
commit b09033e587
2 changed files with 76 additions and 1 deletions

View File

@@ -1,7 +1,8 @@
import { describe, expect, it, vi } from "vitest";
import { afterEach, describe, expect, it, vi } from "vitest";
import {
createSlackTurnDeliveryTracker,
isSlackStreamingEnabled,
resetSlackStreamRecipientTeamCacheForTests,
resolveSlackDisableBlockStreaming,
resolveSlackStreamRecipientTeamId,
resolveSlackStreamingThreadHint,
@@ -9,6 +10,10 @@ import {
shouldInitializeSlackDraftStream,
} from "./dispatch.js";
afterEach(() => {
resetSlackStreamRecipientTeamCacheForTests();
});
describe("slack native streaming defaults", () => {
it("is enabled for partial mode when native streaming is on", () => {
expect(isSlackStreamingEnabled({ mode: "partial", nativeStreaming: true })).toBe(true);
@@ -93,6 +98,26 @@ describe("slack native streaming recipient team", () => {
}),
).toBe("T_LOCAL");
});
it("caches resolved user teams for repeated stream starts", async () => {
const usersInfo = vi.fn(async () => ({
user: { team_id: "T_LOOKUP" },
}));
const params = {
client: {
users: {
info: usersInfo,
},
} as never,
token: "xoxb-test",
userId: "U_REMOTE",
fallbackTeamId: "T_LOCAL",
};
await expect(resolveSlackStreamRecipientTeamId(params)).resolves.toBe("T_LOOKUP");
await expect(resolveSlackStreamRecipientTeamId(params)).resolves.toBe("T_LOOKUP");
expect(usersInfo).toHaveBeenCalledTimes(1);
});
});
describe("slack turn delivery tracker", () => {

View File

@@ -177,6 +177,9 @@ type SlackTurnDeliveryAttempt = {
textOverride?: string;
};
const SLACK_STREAM_RECIPIENT_TEAM_CACHE_MAX = 2000;
const slackStreamRecipientTeamCache = new Map<string, string>();
function buildSlackTurnDeliveryKey(params: SlackTurnDeliveryAttempt): string | null {
const reply = resolveSendableOutboundReplyParts(params.payload, {
text: params.textOverride,
@@ -195,6 +198,48 @@ function buildSlackTurnDeliveryKey(params: SlackTurnDeliveryAttempt): string | n
});
}
function readSlackStreamRecipientTeamCache(params: {
fallbackTeamId?: string;
userId?: string;
}): string | undefined {
if (!params.fallbackTeamId || !params.userId) {
return undefined;
}
const cacheKey = `${params.fallbackTeamId}:${params.userId}`;
const cached = slackStreamRecipientTeamCache.get(cacheKey);
if (!cached) {
return undefined;
}
slackStreamRecipientTeamCache.delete(cacheKey);
slackStreamRecipientTeamCache.set(cacheKey, cached);
return cached;
}
function rememberSlackStreamRecipientTeam(params: {
fallbackTeamId?: string;
userId?: string;
teamId: string;
}): void {
if (!params.fallbackTeamId || !params.userId) {
return;
}
const cacheKey = `${params.fallbackTeamId}:${params.userId}`;
if (slackStreamRecipientTeamCache.has(cacheKey)) {
slackStreamRecipientTeamCache.delete(cacheKey);
}
slackStreamRecipientTeamCache.set(cacheKey, params.teamId);
if (slackStreamRecipientTeamCache.size > SLACK_STREAM_RECIPIENT_TEAM_CACHE_MAX) {
const oldest = slackStreamRecipientTeamCache.keys().next().value;
if (oldest) {
slackStreamRecipientTeamCache.delete(oldest);
}
}
}
export function resetSlackStreamRecipientTeamCacheForTests(): void {
slackStreamRecipientTeamCache.clear();
}
export function createSlackTurnDeliveryTracker() {
const deliveredKeys = new Set<string>();
return {
@@ -231,6 +276,10 @@ export async function resolveSlackStreamRecipientTeamId(params: {
userId?: PreparedSlackMessage["message"]["user"];
fallbackTeamId?: string;
}): Promise<string | undefined> {
const cachedTeamId = readSlackStreamRecipientTeamCache(params);
if (cachedTeamId) {
return cachedTeamId;
}
if (params.userId) {
try {
const info = await params.client.users.info({
@@ -239,6 +288,7 @@ export async function resolveSlackStreamRecipientTeamId(params: {
});
const teamId = info.user?.team_id ?? info.user?.profile?.team;
if (teamId) {
rememberSlackStreamRecipientTeam({ ...params, teamId });
return teamId;
}
} catch (err) {