@@ -2052,8 +2052,8 @@ private:
2052
2052
2053
2053
class Worker ::Isolate::InspectorChannelImpl final : public v8_inspector::V8Inspector::Channel {
2054
2054
public:
2055
- InspectorChannelImpl (kj::Own<const Worker::Isolate> isolateParam, kj::WebSocket& webSocket)
2056
- : ioHandler(webSocket), state(kj::heap<State>(this , kj::mv(isolateParam))) {
2055
+ InspectorChannelImpl (kj::Own<const Worker::Isolate> isolateParam, kj::WebSocket& webSocket, kj::Timer& timer )
2056
+ : ioHandler(webSocket, timer ), state(kj::heap<State>(this , kj::mv(isolateParam))) {
2057
2057
ioHandler.connect (*this );
2058
2058
}
2059
2059
@@ -2286,8 +2286,8 @@ private:
2286
2286
// the InspectorChannelImpl and the InspectorClient.
2287
2287
class WebSocketIoHandler final {
2288
2288
public:
2289
- WebSocketIoHandler (kj::WebSocket& webSocket)
2290
- : webSocket(webSocket) {
2289
+ WebSocketIoHandler (kj::WebSocket& webSocket, kj::Timer& timer )
2290
+ : webSocket(webSocket), timer(timer) {
2291
2291
// Assume we are being instantiated on the InspectorService thread, the thread that will do
2292
2292
// I/O for CDP messages. Messages are delivered to the InspectorChannelImpl on the Isolate thread.
2293
2293
outgoingQueueNotifier = XThreadNotifier::create ();
@@ -2424,6 +2424,18 @@ private:
2424
2424
}
2425
2425
2426
2426
kj::Promise<void > outgoingLoop () {
2427
+ // Pause before sending outgoing messages when a connection is first received. V8 starts
2428
+ // sending messages as soon as it sees there is an inspector client. The process at the
2429
+ // other end of the pipe may not be ready for messages right away (it looks like Chrome does
2430
+ // not render CDP messages, and responses, exchanged before the inspector window is rendered).
2431
+ //
2432
+ // The pause time, 300ms, is experimentally determined on a couple of different dev boxes.
2433
+ // Stepping up from 50ms in 50ms increments, 250ms is the lowest value that seems to
2434
+ // consistently result in the expected behaviour. 300ms allows for a little more noise.
2435
+ //
2436
+ // (Bug: https://github.com/cloudflare/workerd/issues/1201, needs some more investigation).
2437
+ co_await timer.afterDelay (300 * kj::MILLISECONDS);
2438
+
2427
2439
for (;;) {
2428
2440
co_await outgoingQueueNotifier->awaitNotification ();
2429
2441
try {
@@ -2454,6 +2466,7 @@ private:
2454
2466
kj::Own<XThreadNotifier> outgoingQueueNotifier;
2455
2467
2456
2468
kj::WebSocket& webSocket; // only accessed on the InspectorService thread.
2469
+ kj::Timer& timer;
2457
2470
std::atomic_bool receivedClose; // accessed on any thread (only transitions false -> true).
2458
2471
kj::Maybe<InspectorChannelImpl&> channel; // only accessed on the isolate thread.
2459
2472
};
@@ -2645,7 +2658,7 @@ kj::Promise<void> Worker::Isolate::attachInspector(
2645
2658
2646
2659
lockedSelf.impl ->inspectorClient .setInspectorTimerInfo (timer, timerOffset);
2647
2660
2648
- auto channel = kj::heap<Worker::Isolate::InspectorChannelImpl>(kj::atomicAddRef (*this ), webSocket);
2661
+ auto channel = kj::heap<Worker::Isolate::InspectorChannelImpl>(kj::atomicAddRef (*this ), webSocket, timer );
2649
2662
lockedSelf.currentInspectorSession = *channel;
2650
2663
lockedSelf.impl ->inspectorClient .setChannel (*channel);
2651
2664
0 commit comments