fix(gateway): invalidate channel caches on re-pin

This commit is contained in:
Ayaan Zaidi
2026-03-25 09:24:46 +05:30
committed by Peter Steinberger
parent fae4492d92
commit ef5e554def
2 changed files with 35 additions and 1 deletions

View File

@@ -1,6 +1,8 @@
import { afterEach, describe, expect, it } from "vitest";
import { getChannelPlugin } from "../channels/plugins/registry.js";
import { createEmptyPluginRegistry } from "./registry-empty.js";
import {
getActivePluginRegistryVersion,
getActivePluginChannelRegistry,
pinActivePluginChannelRegistry,
releasePinnedPluginChannelRegistry,
@@ -34,6 +36,29 @@ describe("channel registry pinning", () => {
expect(getActivePluginChannelRegistry()!.channels).toHaveLength(1);
});
it("re-pin invalidates cached channel lookups", () => {
const setup = createEmptyPluginRegistry();
const setupPlugin = { id: "slack", meta: {} } as never;
setup.channels = [{ plugin: setupPlugin }] as never;
setActivePluginRegistry(setup);
pinActivePluginChannelRegistry(setup);
expect(getChannelPlugin("slack")).toBe(setupPlugin);
const full = createEmptyPluginRegistry();
const fullPlugin = { id: "slack", meta: {} } as never;
full.channels = [{ plugin: fullPlugin }] as never;
setActivePluginRegistry(full);
expect(getChannelPlugin("slack")).toBe(setupPlugin);
const versionBeforeRepin = getActivePluginRegistryVersion();
pinActivePluginChannelRegistry(full);
expect(getActivePluginRegistryVersion()).toBe(versionBeforeRepin + 1);
expect(getChannelPlugin("slack")).toBe(fullPlugin);
});
it("updates channel registry on swap when not pinned", () => {
const first = createEmptyPluginRegistry();
setActivePluginRegistry(first);

View File

@@ -106,16 +106,25 @@ export function resolveActivePluginHttpRouteRegistry(fallback: PluginRegistry):
* gateway startup after the initial plugin load so that config-schema reads
* and other non-primary registry loads cannot evict channel plugins. */
export function pinActivePluginChannelRegistry(registry: PluginRegistry) {
if (state.channelRegistry === registry && state.channelRegistryPinned) {
return;
}
state.channelRegistry = registry;
state.channelRegistryPinned = true;
state.version += 1;
}
export function releasePinnedPluginChannelRegistry(registry?: PluginRegistry) {
if (registry && state.channelRegistry !== registry) {
return;
}
const nextChannelRegistry = state.registry;
if (state.channelRegistry === nextChannelRegistry && !state.channelRegistryPinned) {
return;
}
state.channelRegistryPinned = false;
state.channelRegistry = state.registry;
state.channelRegistry = nextChannelRegistry;
state.version += 1;
}
/** Return the registry that should be used for channel plugin resolution.