mirror of
https://github.com/affaan-m/ECC.git
synced 2026-09-10 11:47:54 +02:00
fix: prevent plan canvas connection starvation
This commit is contained in:
@@ -13,6 +13,9 @@ opening a second Plan Canvas in one agent chat.
|
||||
disable or stall the page.
|
||||
2. As a reviewer opening a plan with Mermaid diagrams, I want the Canvas page to
|
||||
finish loading even when the Mermaid CDN is slow or unavailable.
|
||||
3. As a reviewer with several Canvas tabs still open, I want the next Canvas to
|
||||
receive and render its document instead of waiting forever for a browser
|
||||
connection slot.
|
||||
|
||||
## Task report
|
||||
|
||||
@@ -43,6 +46,36 @@ opening a second Plan Canvas in one agent chat.
|
||||
failures.
|
||||
- GREEN checkpoint: `7fc31254 fix: keep mermaid from blocking canvas load`.
|
||||
|
||||
### Stop open canvases from exhausting the browser connection pool
|
||||
|
||||
- RED: the normal Chrome profile showed an `Untitled` blank tab with its load
|
||||
indicator running indefinitely. `lsof -nP -iTCP:4517` showed exactly six
|
||||
established connections from Chrome's network service to Plan Canvas. Each
|
||||
older Canvas tab owned one permanent `EventSource`, exhausting Chromium's
|
||||
six-connection HTTP/1 pool before the next document request could receive a
|
||||
byte.
|
||||
- RED: the focused integration test failed because `/client.js` still created
|
||||
`EventSource`, `/api/session/:key/state` did not exist, `/events/:key` held
|
||||
its response open, and health still advertised protocol 2.
|
||||
- GREEN: protocol 3 replaces per-tab EventSource streams with one-second,
|
||||
finite state requests carrying chat, presence, session status, and artifact
|
||||
revision. Polls are sequential and abort after five seconds, so they cannot
|
||||
pile up. Legacy `/events/:key` now returns HTTP 204, the status that tells an
|
||||
existing EventSource client not to reconnect after the server upgrade.
|
||||
- GREEN: `node tests/scripts/plan-canvas.test.js` produced 31 passes and 0
|
||||
failures, including preservation of the active-browser idle lifecycle.
|
||||
Focused ESLint and `git diff --check` passed.
|
||||
- BROWSER: nine Canvas tabs were opened in one Chrome automation profile on an
|
||||
isolated protocol-3 server. Every tab reached `document.readyState =
|
||||
complete`, exposed its expected plan heading through the iframe accessibility
|
||||
tree, and reported zero EventSource resources. Two shared keep-alive sockets
|
||||
served the nine tabs at the observation point.
|
||||
- DESKTOP: the normal Chrome profile kept the original blank protocol-2 tab
|
||||
visible while three protocol-3 canvases on the isolated port rendered the
|
||||
Sandbox Execution Fabric, Feature Fleet, and ECC 2 to ECC 3 plans. A captured
|
||||
desktop-window image showed all three rendered tabs and live `agent listening`
|
||||
presence.
|
||||
|
||||
## Test specification
|
||||
|
||||
| # | What is guaranteed | Test target | Type | Result |
|
||||
@@ -52,30 +85,44 @@ opening a second Plan Canvas in one agent chat.
|
||||
| 3 | Mermaid remote enhancement starts only after document load | `a plan containing mermaid serves the themed Mermaid loader` | Integration | PASS |
|
||||
| 4 | Open, browser load, await, feedback, reply, approval, reopen, end, and stop still work together | `tests/integration/plan-canvas-e2e.test.js` | End to end | PASS |
|
||||
| 5 | The large ECC 2 to ECC 3 master plan bootstraps under blocked local storage | Headless Chrome DOM and screenshot check against `/canvas/24af75d4c4fe` | Browser | PASS |
|
||||
| 6 | The browser client never reserves one permanent HTTP connection per open Canvas | `browser client uses finite polling instead of one permanent connection per canvas` | Integration | PASS |
|
||||
| 7 | Old EventSource clients stop reconnecting after upgrading the server | `legacy EventSource endpoint retires without reconnecting` | Integration | PASS |
|
||||
| 8 | Browser polling carries chat, presence, end state, and artifact revision | Browser-state integration cases in `tests/scripts/plan-canvas.test.js` | Integration | PASS |
|
||||
| 9 | More than Chromium's six HTTP/1 connection slots can coexist without blocking a new Canvas | Nine-tab Chrome DOM, accessibility-tree, resource-timing, and screenshot run | Browser | PASS |
|
||||
| 10 | An actively viewed Canvas keeps the shared server alive through finite polls | `finite browser polls keep an actively viewed canvas server alive` | Integration | PASS |
|
||||
|
||||
## Coverage and full-suite evidence
|
||||
|
||||
`npm run coverage` passed all 3,993 discovered tests with these project totals:
|
||||
`npm run coverage` passed all 3,996 discovered tests with these project totals:
|
||||
|
||||
- Statements: 88.98%
|
||||
- Branches: 80.66%
|
||||
- Functions: 94.32%
|
||||
- Branches: 80.65%
|
||||
- Functions: 94.34%
|
||||
- Lines: 88.98%
|
||||
|
||||
The `scripts/lib/plan-canvas` group reached 98.38% statements, 88.2% branches,
|
||||
98.64% functions, and 98.38% lines. Focused ESLint checks passed for every
|
||||
The `scripts/lib/plan-canvas` group reached 98.53% statements, 87.82% branches,
|
||||
100% functions, and 98.53% lines. Focused ESLint checks passed for every
|
||||
modified JavaScript test and production file.
|
||||
|
||||
## Browser evidence and known gaps
|
||||
|
||||
The live shared server was initially process `15351`, started from the older
|
||||
`ecc-tiered-sandbox` worktree, and served an unguarded `localStorage` client even
|
||||
when invoked from current main. The patched CLI replaced it with the isolated
|
||||
worktree server and restored persisted sessions. Two real plan sessions then
|
||||
opened successfully. Headless Chrome with local storage disabled completed the
|
||||
large master-plan DOM load in about two seconds and produced a rendered Canvas
|
||||
screenshot.
|
||||
when invoked from current main. The first patch replaced it with the isolated
|
||||
worktree server and restored persisted sessions. That did not establish the
|
||||
reported bug was fixed: HTTP 200 responses and a fresh-profile screenshot did
|
||||
not exercise the saturated normal browser profile.
|
||||
|
||||
Chrome was exercised directly on macOS. Safari and Firefox were not run. The
|
||||
fix relies only on standard health JSON, dynamic `import()`, and the standard
|
||||
window `load` event.
|
||||
The corrected investigation captured the real blank tab, its six live browser
|
||||
connections, and the exact release-preview session behind it. The final browser
|
||||
run used an isolated protocol-3 server on port 4518 so other agents could not
|
||||
replace the executable under test. It rendered the actual in-progress Sandbox
|
||||
Execution Fabric from the tiered-sandbox worktree, plus Feature Fleet and the
|
||||
ECC 2 to ECC 3 master plan, in the normal desktop Chrome profile. Active agent
|
||||
listeners remained attached to all three.
|
||||
|
||||
Chrome was exercised directly on macOS through both the user's normal profile
|
||||
and a browser-automation profile. Safari and Firefox were not run. The
|
||||
connection-pool fix relies on ordinary finite `fetch` requests, `AbortController`,
|
||||
HTTP 204 EventSource retirement behavior, and file metadata for live-reload
|
||||
revision checks.
|
||||
|
||||
Reference in New Issue
Block a user