@@ -28,14 +28,14 @@ const wsReadLimit = 8 * 1024 * 1024
2828//
2929// Lock ordering (outer → inner):
3030//
31- // lifeMu → restartMu → pendReqMu → computed.mu → pendMu → sessionsMu
31+ // restartMu → lifeMu → pendReqMu → computed.mu → pendMu → sessionsMu
3232//
3333// Never acquire a lock that appears later in this order while holding an
3434// earlier one, to prevent deadlock.
3535//
3636// WebSocket concurrency: coder/websocket guarantees that one concurrent Read
3737// and one concurrent Write are safe. The readLoop holds the sole Read; all
38- // writes go through sendMsg , which serialises them with conn.Write's internal
38+ // writes go through send , which serialises them with conn.Write's internal
3939// lock. No external write mutex is needed.
4040type Monitor struct {
4141 upstreamMgr UpstreamProvider
@@ -69,8 +69,9 @@ type Monitor struct {
6969 bindingRateMu sync.Mutex
7070 bindingLastSeen map [string ]time.Time // sessionID → last accepted binding event time
7171
72- // asyncWg tracks short-lived goroutines only (fetchResponseBody, enableDomains,
73- // initSession). readLoop and subscribeToUpstream are not tracked; they exit via context.
72+ // asyncWg tracks all goroutines except readLoop (which is tracked via done).
73+ // subscribeToUpstream and sweepPendingRequests are included so Stop() can
74+ // wait for them to exit before returning.
7475 asyncWg sync.WaitGroup
7576 restartMu sync.Mutex // serializes handleUpstreamRestart to prevent overlapping reconnects
7677
@@ -138,7 +139,7 @@ func (m *Monitor) getLifecycleCtx() context.Context {
138139
139140// Start begins CDP capture. Restarts if already running.
140141// Not concurrency-safe; callers must serialize Start calls.
141- func (m * Monitor ) Start (parentCtx context.Context ) error {
142+ func (m * Monitor ) Start (_ context.Context ) error {
142143 m .Stop () // no-op if not running
143144
144145 devtoolsURL := m .upstreamMgr .Current ()
@@ -168,8 +169,8 @@ func (m *Monitor) Start(parentCtx context.Context) error {
168169 m .log .Info ("cdpmonitor: started" , "url" , devtoolsURL )
169170
170171 go m .readLoop (ctx )
171- go m .subscribeToUpstream (ctx )
172- go m .sweepPendingRequests (ctx )
172+ m . asyncWg . Go ( func () { m .subscribeToUpstream (ctx ) } )
173+ m . asyncWg . Go ( func () { m .sweepPendingRequests (ctx ) } )
173174 m .asyncWg .Go (func () { m .initSession (ctx ) })
174175
175176 return nil
@@ -452,12 +453,12 @@ func (m *Monitor) attachExistingTargets(ctx context.Context) {
452453 if err != nil {
453454 return
454455 }
455- var attached struct {
456+ var attachResp struct {
456457 SessionID string `json:"sessionId"`
457458 }
458- if json .Unmarshal (res , & attached ) == nil && attached .SessionID != "" {
459- m .enableDomains (ctx , attached .SessionID , targetTypePage )
460- _ = m .injectScript (ctx , attached .SessionID )
459+ if json .Unmarshal (res , & attachResp ) == nil && attachResp .SessionID != "" {
460+ m .enableDomains (ctx , attachResp .SessionID , targetTypePage )
461+ _ = m .injectScript (ctx , attachResp .SessionID )
461462 }
462463 })
463464 }
@@ -554,17 +555,15 @@ func (m *Monitor) handleUpstreamRestart(ctx context.Context, newURL string) {
554555 m .clearState ()
555556
556557 m .asyncWg .Go (func () { m .initSession (ctx ) })
557- m .log .Info ("cdpmonitor: reconnected" , "url" , newURL , "duration_ms" , time .Since (startReconnect ).Milliseconds ())
558+ reconnectDurationMs := time .Since (startReconnect ).Milliseconds ()
559+ m .log .Info ("cdpmonitor: reconnected" , "url" , newURL , "duration_ms" , reconnectDurationMs )
558560
559561 m .publish (events.Event {
560562 Ts : time .Now ().UnixMilli (),
561563 Type : EventMonitorReconnected ,
562564 Category : events .CategorySystem ,
563565 Source : events.Source {Kind : events .KindLocalProcess },
564- Data : json .RawMessage (fmt .Sprintf (
565- `{"reconnect_duration_ms":%d}` ,
566- time .Since (startReconnect ).Milliseconds (),
567- )),
566+ Data : json .RawMessage (fmt .Sprintf (`{"reconnect_duration_ms":%d}` , reconnectDurationMs )),
568567 })
569568}
570569
0 commit comments