fix(electron): preserve HMR connection limits
This commit is contained in:
@@ -19,7 +19,7 @@ The preload bridge exposes desktop-only APIs to the web UI through `window.__OPE
|
|||||||
| File | Purpose |
|
| File | Purpose |
|
||||||
|------|---------|
|
|------|---------|
|
||||||
| `main.mjs` | Electron main process, app lifecycle, windows, menus, deep links, native IPC handlers, updates, local server startup |
|
| `main.mjs` | Electron main process, app lifecycle, windows, menus, deep links, native IPC handlers, updates, local server startup |
|
||||||
| `startup-url-selection.mjs` | Pure bundled/HMR startup probe policy used by main-process URL resolution |
|
| `startup-url-selection.mjs` | Pure bundled/HMR startup probe and loopback connection-limit policy |
|
||||||
| `preload.mjs` | Safe bridge from the rendered UI to Electron IPC |
|
| `preload.mjs` | Safe bridge from the rendered UI to Electron IPC |
|
||||||
| `ssh-manager.mjs` | SSH host import, connection lifecycle, tunnel/port forwarding helpers |
|
| `ssh-manager.mjs` | SSH host import, connection lifecycle, tunnel/port forwarding helpers |
|
||||||
| `scripts/electron-dev.mjs` | Desktop dev launcher with Vite HMR support |
|
| `scripts/electron-dev.mjs` | Desktop dev launcher with Vite HMR support |
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import updaterPkg from 'electron-updater';
|
|||||||
import { ElectronSshManager } from './ssh-manager.mjs';
|
import { ElectronSshManager } from './ssh-manager.mjs';
|
||||||
import { createTrayController } from './tray.mjs';
|
import { createTrayController } from './tray.mjs';
|
||||||
import { resolveManagedOpenCodeCwd } from './opencode-cwd.mjs';
|
import { resolveManagedOpenCodeCwd } from './opencode-cwd.mjs';
|
||||||
import { resolveStartupUrlProbePlan } from './startup-url-selection.mjs';
|
import { resolveStartupUrlProbePlan, shouldIgnoreLoopbackConnectionLimit } from './startup-url-selection.mjs';
|
||||||
import { sanitizeRuntimeRequestHeaders } from './runtime-request-headers.mjs';
|
import { sanitizeRuntimeRequestHeaders } from './runtime-request-headers.mjs';
|
||||||
import { assertUpdaterCapability } from './updater-capability.mjs';
|
import { assertUpdaterCapability } from './updater-capability.mjs';
|
||||||
import { checkForDesktopUpdate } from './updater-check.mjs';
|
import { checkForDesktopUpdate } from './updater-check.mjs';
|
||||||
@@ -89,13 +89,16 @@ if (isDev) {
|
|||||||
}
|
}
|
||||||
app.setAppUserModelId(APP_USER_MODEL_ID);
|
app.setAppUserModelId(APP_USER_MODEL_ID);
|
||||||
app.commandLine.appendSwitch('proxy-bypass-list', '<-loopback>');
|
app.commandLine.appendSwitch('proxy-bypass-list', '<-loopback>');
|
||||||
// Lift Chromium's ~6-connections-per-host cap for the loopback backend. The
|
// Lift Chromium's per-host cap only for bundled UI. Applying this to Vite HMR
|
||||||
// packaged renderer is cross-origin (openchamber-ui:// → http://127.0.0.1), so
|
// lets the renderer request most of the module graph at once, overwhelming the
|
||||||
// every API call also needs a CORS preflight; during startup a few slow
|
// dev server's transform pipeline and leaving the HTML splash visible for up
|
||||||
// OpenCode-proxied requests otherwise hold the whole pool and every other
|
// to a minute before React mounts.
|
||||||
// request — including opening the first session — queues for seconds behind
|
if (shouldIgnoreLoopbackConnectionLimit({
|
||||||
// them. Loopback has no per-host connection cost that the cap protects.
|
development: isDev,
|
||||||
app.commandLine.appendSwitch('ignore-connections-limit', '127.0.0.1,localhost');
|
packagedUi: process.env.OPENCHAMBER_ELECTRON_USE_BUNDLED_UI === '1',
|
||||||
|
})) {
|
||||||
|
app.commandLine.appendSwitch('ignore-connections-limit', '127.0.0.1,localhost');
|
||||||
|
}
|
||||||
|
|
||||||
protocol.registerSchemesAsPrivileged([
|
protocol.registerSchemesAsPrivileged([
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,3 +2,7 @@ export const resolveStartupUrlProbePlan = ({ development, packagedUi, skipLocalS
|
|||||||
probeHmrApi: development === true && packagedUi !== true && skipLocalServer !== true,
|
probeHmrApi: development === true && packagedUi !== true && skipLocalServer !== true,
|
||||||
probeHmrUi: development === true && packagedUi !== true,
|
probeHmrUi: development === true && packagedUi !== true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const shouldIgnoreLoopbackConnectionLimit = ({ development, packagedUi }) => (
|
||||||
|
development !== true || packagedUi === true
|
||||||
|
);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import assert from 'node:assert/strict';
|
import assert from 'node:assert/strict';
|
||||||
import test from 'node:test';
|
import test from 'node:test';
|
||||||
|
|
||||||
import { resolveStartupUrlProbePlan } from './startup-url-selection.mjs';
|
import { resolveStartupUrlProbePlan, shouldIgnoreLoopbackConnectionLimit } from './startup-url-selection.mjs';
|
||||||
|
|
||||||
test('bundled development never probes HMR endpoints', () => {
|
test('bundled development never probes HMR endpoints', () => {
|
||||||
assert.deepEqual(resolveStartupUrlProbePlan({
|
assert.deepEqual(resolveStartupUrlProbePlan({
|
||||||
@@ -46,3 +46,9 @@ test('production does not probe HMR endpoints', () => {
|
|||||||
probeHmrUi: false,
|
probeHmrUi: false,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('keeps Chromium connection limits for the Vite HMR module graph', () => {
|
||||||
|
assert.equal(shouldIgnoreLoopbackConnectionLimit({ development: true, packagedUi: false }), false);
|
||||||
|
assert.equal(shouldIgnoreLoopbackConnectionLimit({ development: true, packagedUi: true }), true);
|
||||||
|
assert.equal(shouldIgnoreLoopbackConnectionLimit({ development: false, packagedUi: false }), true);
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user