Skip to content

Commit 776e5d8

Browse files
committed
Gateway: lazily resolve channel runtime
1 parent 77b1f24 commit 776e5d8

File tree

2 files changed

+24
-3
lines changed

2 files changed

+24
-3
lines changed

src/gateway/server-channels.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,14 @@ type ChannelManagerOptions = {
105105
* @see {@link ChannelGatewayContext.channelRuntime}
106106
*/
107107
channelRuntime?: PluginRuntime["channel"];
108+
/**
109+
* Lazily resolves optional channel runtime helpers for external channel plugins.
110+
*
111+
* Use this when the caller wants to avoid instantiating the full plugin channel
112+
* runtime during gateway startup. The manager only needs the runtime surface once
113+
* a channel account actually starts.
114+
*/
115+
resolveChannelRuntime?: () => PluginRuntime["channel"];
108116
};
109117

110118
type StartChannelOptions = {
@@ -125,7 +133,8 @@ export type ChannelManager = {
125133

126134
// Channel docking: lifecycle hooks (`plugin.gateway`) flow through this manager.
127135
export function createChannelManager(opts: ChannelManagerOptions): ChannelManager {
128-
const { loadConfig, channelLogs, channelRuntimeEnvs, channelRuntime } = opts;
136+
const { loadConfig, channelLogs, channelRuntimeEnvs, channelRuntime, resolveChannelRuntime } =
137+
opts;
129138

130139
const channelStores = new Map<ChannelId, ChannelRuntimeStore>();
131140
// Tracks restart attempts per channel:account. Reset on successful start.
@@ -219,6 +228,10 @@ export function createChannelManager(opts: ChannelManagerOptions): ChannelManage
219228
return next;
220229
};
221230

231+
const getChannelRuntime = (): PluginRuntime["channel"] | undefined => {
232+
return channelRuntime ?? resolveChannelRuntime?.();
233+
};
234+
222235
const startChannelInternal = async (
223236
channelId: ChannelId,
224237
accountId?: string,
@@ -297,6 +310,7 @@ export function createChannelManager(opts: ChannelManagerOptions): ChannelManage
297310
});
298311

299312
const log = channelLogs[channelId];
313+
const resolvedChannelRuntime = getChannelRuntime();
300314
const task = startAccount({
301315
cfg,
302316
accountId: id,
@@ -306,7 +320,7 @@ export function createChannelManager(opts: ChannelManagerOptions): ChannelManage
306320
log,
307321
getStatus: () => getRuntime(channelId, id),
308322
setStatus: (next) => setRuntime(channelId, id, next),
309-
...(channelRuntime ? { channelRuntime } : {}),
323+
...(resolvedChannelRuntime ? { channelRuntime: resolvedChannelRuntime } : {}),
310324
});
311325
const trackedPromise = Promise.resolve(task)
312326
.catch((err) => {

src/gateway/server.impl.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,13 @@ const logDiscovery = log.child("discovery");
138138
const logTailscale = log.child("tailscale");
139139
const logChannels = log.child("channels");
140140
const logBrowser = log.child("browser");
141+
142+
let cachedChannelRuntime: ReturnType<typeof createPluginRuntime>["channel"] | null = null;
143+
144+
function getChannelRuntime() {
145+
cachedChannelRuntime ??= createPluginRuntime().channel;
146+
return cachedChannelRuntime;
147+
}
141148
const logHealth = log.child("health");
142149
const logCron = log.child("cron");
143150
const logReload = log.child("reload");
@@ -575,7 +582,7 @@ export async function startGatewayServer(
575582
loadConfig,
576583
channelLogs,
577584
channelRuntimeEnvs,
578-
channelRuntime: createPluginRuntime().channel,
585+
resolveChannelRuntime: getChannelRuntime,
579586
});
580587
const getReadiness = createReadinessChecker({
581588
channelManager,

0 commit comments

Comments
 (0)