Skip to content

feat: concurrent dispatch for fs/workspace WebSocket requests#37

Merged
veithly merged 2 commits intomasterfrom
feat/concurrent-fs-dispatch
Mar 16, 2026
Merged

feat: concurrent dispatch for fs/workspace WebSocket requests#37
veithly merged 2 commits intomasterfrom
feat/concurrent-fs-dispatch

Conversation

@veithly
Copy link
Contributor

@veithly veithly commented Mar 16, 2026

Summary

  • head-of-line blocking fix: fs/workspace RPC methods (fs.list, fs.stat, fs.read, fs.write, etc.) are now dispatched as concurrent asyncio.Tasks instead of being awaited serially in the message loop, eliminating request queuing when clients send multiple fs requests in quick succession
  • per-path write locks: added _PathLockManager to WorkspaceFSService that serializes concurrent writes to the same path while allowing different paths to write in parallel; locks are acquired in sorted order to prevent deadlock on rename
  • WebSocket send safety: added send_lock per Connection to serialize send_json calls and prevent frame interleaving from concurrent tasks

Changes

File Change
handler.py Added _CONCURRENT_METHODS frozenset; message loop now uses create_task for fs/workspace methods; _concurrent_tasks set tracks in-flight tasks for cleanup on disconnect
manager.py Connection dataclass gains send_lock: asyncio.Lock; send_message wraps send_json with it
workspace_fs.py New _PathLockManager class; write/mkdir/rename/remove wrapped with path locks; read methods (list/stat/read) unchanged
tests/test_workspace_fs_service.py 5 new concurrency tests

Test Plan

  • test_concurrent_reads_run_in_parallel — 15 parallel read ops complete correctly
  • test_concurrent_writes_same_path_serialized — same-path writes do not overlap (verified via timing)
  • test_concurrent_writes_different_paths_parallel — different-path writes run in parallel (elapsed < 120ms for 3×50ms writes)
  • test_rename_no_deadlock — rename with two-path lock completes within 2s timeout
  • test_path_lock_cleanup_PathLockManager cleans up lock entries after release

veithly and others added 2 commits March 13, 2026 00:23
Previously all non-chat WS requests were processed serially in the
message loop, causing head-of-line blocking when clients send multiple
fs.list/fs.read/etc. requests in quick succession.

Changes:
- handler.py: dispatch fs/workspace methods as asyncio tasks so they
  run concurrently; track tasks for cleanup on disconnect
- manager.py: add per-connection send_lock to prevent WebSocket frame
  interleaving from concurrent tasks
- workspace_fs.py: add _PathLockManager with per-path write locks
  (sorted acquisition order to prevent deadlock); read ops remain
  lock-free
- tests: add 5 concurrency tests covering parallel reads, serialized
  same-path writes, parallel different-path writes, rename deadlock
  safety, and lock cleanup
@veithly veithly merged commit 7b6a569 into master Mar 16, 2026
2 checks passed
@joeqian10 joeqian10 deleted the feat/concurrent-fs-dispatch branch March 17, 2026 10:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants