refactor: isolate chat hot paths and lazy server watchers
Split static history from live tail, stabilize chat data identities, and reduce scroll-shell churn so old viewport content stops waking on stream deltas. Also defer watcher startup and health polling so idle runtime work better matches actual usage.
This commit is contained in:
@@ -339,6 +339,7 @@ let isExternalOpenCode = false;
|
||||
let exitOnShutdown = true;
|
||||
let uiAuthController = null;
|
||||
let activeTunnelController = null;
|
||||
let globalWatcherStartPromise = null;
|
||||
const tunnelProviderRegistry = createTunnelProviderRegistry([
|
||||
createCloudflareTunnelProvider(),
|
||||
]);
|
||||
@@ -739,13 +740,24 @@ const waitForOpenCodeReady = (...args) => openCodeLifecycleRuntime.waitForOpenCo
|
||||
const waitForAgentPresence = (...args) => openCodeLifecycleRuntime.waitForAgentPresence(...args);
|
||||
const refreshOpenCodeAfterConfigChange = (...args) => openCodeLifecycleRuntime.refreshOpenCodeAfterConfigChange(...args);
|
||||
const startHealthMonitoring = () => openCodeLifecycleRuntime.startHealthMonitoring(HEALTH_CHECK_INTERVAL);
|
||||
const ensureGlobalWatcherStarted = async () => {
|
||||
if (globalWatcherStartPromise) {
|
||||
return globalWatcherStartPromise;
|
||||
}
|
||||
|
||||
globalWatcherStartPromise = openCodeWatcherRuntime.start().catch((error) => {
|
||||
globalWatcherStartPromise = null;
|
||||
throw error;
|
||||
});
|
||||
|
||||
return globalWatcherStartPromise;
|
||||
};
|
||||
const bootstrapOpenCodeAtStartup = async (...args) => {
|
||||
await openCodeLifecycleRuntime.bootstrapOpenCodeAtStartup(...args);
|
||||
scheduleOpenCodeApiDetection();
|
||||
startHealthMonitoring();
|
||||
void openCodeWatcherRuntime.start().catch((error) => {
|
||||
console.warn(`Global event watcher startup failed: ${error?.message || error}`);
|
||||
});
|
||||
if (openCodeLifecycleState.openCodeProcess && !openCodeLifecycleState.isExternalOpenCode) {
|
||||
startHealthMonitoring();
|
||||
}
|
||||
};
|
||||
const killProcessOnPort = (...args) => openCodeLifecycleRuntime.killProcessOnPort(...args);
|
||||
|
||||
@@ -871,6 +883,7 @@ async function main(options = {}) {
|
||||
resolveZenModel,
|
||||
sayTTSCapability,
|
||||
ensurePushInitialized,
|
||||
ensureGlobalWatcherStarted,
|
||||
getOrCreateVapidKeys,
|
||||
getUiSessionTokenFromRequest,
|
||||
writeSettingsToDisk,
|
||||
|
||||
@@ -26,6 +26,7 @@ export const registerNotificationRoutes = (app, dependencies) => {
|
||||
const {
|
||||
uiAuthController,
|
||||
ensurePushInitialized,
|
||||
ensureGlobalWatcherStarted,
|
||||
getOrCreateVapidKeys,
|
||||
getUiSessionTokenFromRequest,
|
||||
readSettingsFromDiskMigrated,
|
||||
@@ -45,6 +46,17 @@ export const registerNotificationRoutes = (app, dependencies) => {
|
||||
setPushInitialized,
|
||||
} = dependencies;
|
||||
|
||||
const ensureSessionWatcher = async () => {
|
||||
if (typeof ensureGlobalWatcherStarted !== 'function') {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await ensureGlobalWatcherStarted();
|
||||
} catch (error) {
|
||||
console.warn('[OpenCodeWatcher] lazy start failed:', error?.message ?? error);
|
||||
}
|
||||
};
|
||||
|
||||
app.get('/api/push/vapid-public-key', async (_req, res) => {
|
||||
try {
|
||||
await ensurePushInitialized();
|
||||
@@ -58,6 +70,7 @@ export const registerNotificationRoutes = (app, dependencies) => {
|
||||
|
||||
app.post('/api/push/subscribe', async (req, res) => {
|
||||
await ensurePushInitialized();
|
||||
await ensureSessionWatcher();
|
||||
|
||||
const uiToken = uiAuthController?.ensureSessionToken
|
||||
? await uiAuthController.ensureSessionToken(req, res)
|
||||
@@ -146,10 +159,12 @@ export const registerNotificationRoutes = (app, dependencies) => {
|
||||
});
|
||||
|
||||
app.get('/api/session-activity', (_req, res) => {
|
||||
void ensureSessionWatcher();
|
||||
res.json(getSessionActivitySnapshot());
|
||||
});
|
||||
|
||||
app.get('/api/sessions/snapshot', (_req, res) => {
|
||||
app.get('/api/sessions/snapshot', async (_req, res) => {
|
||||
await ensureSessionWatcher();
|
||||
res.json({
|
||||
statusSessions: getSessionStateSnapshot(),
|
||||
attentionSessions: getSessionAttentionSnapshot(),
|
||||
@@ -157,7 +172,8 @@ export const registerNotificationRoutes = (app, dependencies) => {
|
||||
});
|
||||
});
|
||||
|
||||
app.get('/api/sessions/status', (_req, res) => {
|
||||
app.get('/api/sessions/status', async (_req, res) => {
|
||||
await ensureSessionWatcher();
|
||||
const snapshot = getSessionStateSnapshot();
|
||||
res.json({
|
||||
sessions: snapshot,
|
||||
@@ -165,7 +181,8 @@ export const registerNotificationRoutes = (app, dependencies) => {
|
||||
});
|
||||
});
|
||||
|
||||
app.get('/api/sessions/:id/status', (req, res) => {
|
||||
app.get('/api/sessions/:id/status', async (req, res) => {
|
||||
await ensureSessionWatcher();
|
||||
const sessionId = req.params.id;
|
||||
const state = getSessionState(sessionId);
|
||||
|
||||
@@ -182,7 +199,8 @@ export const registerNotificationRoutes = (app, dependencies) => {
|
||||
});
|
||||
});
|
||||
|
||||
app.get('/api/sessions/attention', (_req, res) => {
|
||||
app.get('/api/sessions/attention', async (_req, res) => {
|
||||
await ensureSessionWatcher();
|
||||
const snapshot = getSessionAttentionSnapshot();
|
||||
res.json({
|
||||
sessions: snapshot,
|
||||
@@ -190,7 +208,8 @@ export const registerNotificationRoutes = (app, dependencies) => {
|
||||
});
|
||||
});
|
||||
|
||||
app.get('/api/sessions/:id/attention', (req, res) => {
|
||||
app.get('/api/sessions/:id/attention', async (req, res) => {
|
||||
await ensureSessionWatcher();
|
||||
const sessionId = req.params.id;
|
||||
const state = getSessionAttentionState(sessionId);
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ export const createBootstrapRuntime = (dependencies) => {
|
||||
resolveZenModel,
|
||||
sayTTSCapability,
|
||||
ensurePushInitialized,
|
||||
ensureGlobalWatcherStarted,
|
||||
getOrCreateVapidKeys,
|
||||
getUiSessionTokenFromRequest,
|
||||
writeSettingsToDisk,
|
||||
@@ -74,6 +75,7 @@ export const createBootstrapRuntime = (dependencies) => {
|
||||
registerNotificationRoutes(app, {
|
||||
uiAuthController,
|
||||
ensurePushInitialized,
|
||||
ensureGlobalWatcherStarted,
|
||||
getOrCreateVapidKeys,
|
||||
getUiSessionTokenFromRequest,
|
||||
readSettingsFromDiskMigrated,
|
||||
|
||||
Reference in New Issue
Block a user