You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
perf: Reduce PTY read latency and fix lock contention #53
The current PTY read loop and session management have latency and contention issues that affect terminal responsiveness, especially under high-volume output (e.g., seq 1 10000).
These are changes to app.py and static/poll-worker.js only. They don't require the OpenCode fork, spawner app, or any other PR #52 components. Extracting them keeps the review focused and the blast radius small.
These perf fixes are still valuable and should be cherry-picked from PR #52 as a standalone change. Independent of the OpenCode fork — just changes to app.py and static/poll-worker.js.
Closing — the meaningful work was completed in PR #48. The 3 remaining items don't warrant changes:
select() timeout 500ms → 50ms — select returns immediately when data is available. The 500ms is only the idle sleep before checking if the process died. Reducing it doesn't improve output latency at all — just checks for dead processes more often, burning CPU for no user-visible gain.
cleanup_stale_sessions() lock pattern — The global lock is held for microseconds while iterating 1-3 sessions (single-user app). No I/O inside the lock, termination already happens outside it. No contention exists to fix.
Poll-worker interval 100ms → 50ms — HTTP polling is now a fallback only (PR #48 made WebSocket primary). When WS is active, the poll-worker is stopped entirely. Optimizing the degraded fallback path by 50ms isn't worth 2x request volume.
PR #48 shipped the changes that mattered: per-session locks (real contention fix) and WebSocket I/O (eliminated polling latency).
Activity
datasciencemonkey commentedon Mar 11, 2026
These perf fixes are still valuable and should be cherry-picked from PR #52 as a standalone change. Independent of the OpenCode fork — just changes to app.py and static/poll-worker.js.
datasciencemonkey commentedon Mar 12, 2026
Resolved by PR #48 — per-session locks replaced global lock, WebSocket I/O eliminated polling latency, thread pool increased to 16.
datasciencemonkey commentedon Mar 12, 2026
Reopening — PR #48 addressed item 2 (per-session locks for output batch) but 3 items remain:
select()timeout still 500ms (app.py:490) — should be 50mscleanup_stale_sessions()still holds global lock during iteration (app.py:571) — should snapshot-then-iteratedatasciencemonkey commentedon Mar 12, 2026
Closing — the meaningful work was completed in PR #48. The 3 remaining items don't warrant changes:
select()timeout 500ms → 50ms —selectreturns immediately when data is available. The 500ms is only the idle sleep before checking if the process died. Reducing it doesn't improve output latency at all — just checks for dead processes more often, burning CPU for no user-visible gain.cleanup_stale_sessions()lock pattern — The global lock is held for microseconds while iterating 1-3 sessions (single-user app). No I/O inside the lock, termination already happens outside it. No contention exists to fix.Poll-worker interval 100ms → 50ms — HTTP polling is now a fallback only (PR #48 made WebSocket primary). When WS is active, the poll-worker is stopped entirely. Optimizing the degraded fallback path by 50ms isn't worth 2x request volume.
PR #48 shipped the changes that mattered: per-session locks (real contention fix) and WebSocket I/O (eliminated polling latency).