feat(inspector): attach Chrome DevTools to Web Worker isolates#386
feat(inspector): attach Chrome DevTools to Web Worker isolates#386edusperoni wants to merge 2 commits into
Conversation
Workers were invisible to the debugger: the inspector only served the
main isolate and even dropped worker console output on the floor.
DevTools discovers extra isolates through the Target domain with
flat-session multiplexing, so implement that surface in the runtime:
- Add WorkerInspectorClient: a per-worker V8Inspector + session that
lives entirely on the worker's thread. Incoming CDP messages queue
through a dedicated CFRunLoopSource on the worker's runloop; while
paused at a breakpoint a nested loop on the worker thread pumps the
same queue without re-entering the runloop, so postMessage deliveries
stay queued during a pause (matching Chrome's semantics).
- Turn JsV8InspectorClient into the root session + router: handle
Target.setAutoAttach natively (announce workers via
Target.attachedToTarget, detach on death), route messages carrying a
top-level sessionId to the worker's thread directly from the socket
thread, and make the frontend sender thread-safe. Routing off the
socket thread means a worker stays debuggable while the main isolate
is paused, and vice versa.
- Debugger.pause for a busy worker uses RequestInterrupt keyed by
workerId, so a late-firing interrupt after worker death is a no-op.
This also fixes the main-session fast path, which used to interrupt
the main isolate for a pause aimed at any session.
- Serve Network.loadNetworkResource and IO.read/IO.close on the socket
thread for any session (sessionId echoed), so worker source maps
load too.
- Route worker console.* to the worker's own inspector and deliver
through V8ConsoleMessageStorage::addMessage instead of the live-only
runtime agent path: messages logged before the frontend attaches (or
before Runtime.enable reaches a session) are stored and replayed as
console history. Applies to the main isolate as well.
- Name execution contexts ("main" / worker script url) so the DevTools
console context selector rows are labeled and selectable.
- Worker lifecycle: inspector is created on the worker thread before
RunModule (debug builds only), terminate() kicks a paused worker out
of its nested pause loop, teardown unregisters the target before the
isolate is disposed, and frontend reconnects reset worker sessions.
waitForDebuggerOnStart (pause new workers before their first line) is
left as future work; workers currently announce waitingForDebugger:
false.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughAdds worker-target DevTools support: main inspector routes session-scoped messages, a WorkerInspectorClient owns per-worker V8 inspector sessions and pause loops, network/IO handlers become session-aware, console logs are forwarded per-worker, and worker inspectors are created/destroyed during worker lifecycle. ChangesWorker Inspector Support
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Workers were invisible to the debugger: the inspector only served the main isolate and even dropped worker console output on the floor. DevTools discovers extra isolates through the Target domain with flat-session multiplexing, so implement that surface in the runtime:
waitForDebuggerOnStart (pause new workers before their first line) is left as future work; workers currently announce waitingForDebugger: false.
Summary by CodeRabbit
New Features
Bug Fixes
Chores