Repository: nodejs/node
Pull request: inspector: improve batch diagnostic channel subscriptions

Improve batch diagnostic channel subscriptions in network inspections. This could prevent a channel from mismatches in subscribe/unsubscribe.

Changed files:
filename: lib/internal/inspector/network.js
patch: @@ -1,13 +1,16 @@
 'use strict';
 
 const {
+  ArrayPrototypeForEach,
   NumberMAX_SAFE_INTEGER,
   StringPrototypeToLowerCase,
   Symbol,
 } = primordials;
 
+const dc = require('diagnostics_channel');
 const { now } = require('internal/perf/utils');
 const { MIMEType } = require('internal/mime');
+
 const kInspectorRequestId = Symbol('kInspectorRequestId');
 
 // https://chromedevtools.github.io/devtools-protocol/1-3/Network/#type-ResourceType
@@ -67,10 +70,30 @@ function sniffMimeType(contentType) {
   };
 }
 
+function registerDiagnosticChannels(listenerPairs) {
+  function enable() {
+    ArrayPrototypeForEach(listenerPairs, ({ 0: channel, 1: listener }) => {
+      dc.subscribe(channel, listener);
+    });
+  }
+
+  function disable() {
+    ArrayPrototypeForEach(listenerPairs, ({ 0: channel, 1: listener }) => {
+      dc.unsubscribe(channel, listener);
+    });
+  }
+
+  return {
+    enable,
+    disable,
+  };
+}
+
 module.exports = {
   kInspectorRequestId,
   kResourceType,
   getMonotonicTime,
   getNextRequestId,
+  registerDiagnosticChannels,
   sniffMimeType,
 };

filename: lib/internal/inspector/network_http.js
patch: @@ -13,9 +13,9 @@ const {
   kResourceType,
   getMonotonicTime,
   getNextRequestId,
+  registerDiagnosticChannels,
   sniffMimeType,
 } = require('internal/inspector/network');
-const dc = require('diagnostics_channel');
 const { Network } = require('inspector');
 
 const kRequestUrl = Symbol('kRequestUrl');
@@ -129,19 +129,8 @@ function onClientResponseFinish({ request, response }) {
   });
 }
 
-function enable() {
-  dc.subscribe('http.client.request.created', onClientRequestCreated);
-  dc.subscribe('http.client.request.error', onClientRequestError);
-  dc.subscribe('http.client.response.finish', onClientResponseFinish);
-}
-
-function disable() {
-  dc.unsubscribe('http.client.request.created', onClientRequestCreated);
-  dc.unsubscribe('http.client.request.error', onClientRequestError);
-  dc.unsubscribe('http.client.response.finish', onClientResponseFinish);
-}
-
-module.exports = {
-  enable,
-  disable,
-};
+module.exports = registerDiagnosticChannels([
+  ['http.client.request.created', onClientRequestCreated],
+  ['http.client.request.error', onClientRequestError],
+  ['http.client.response.finish', onClientResponseFinish],
+]);

filename: lib/internal/inspector/network_http2.js
patch: @@ -13,9 +13,9 @@ const {
   kResourceType,
   getMonotonicTime,
   getNextRequestId,
+  registerDiagnosticChannels,
   sniffMimeType,
 } = require('internal/inspector/network');
-const dc = require('diagnostics_channel');
 const { Network } = require('inspector');
 const {
   HTTP2_HEADER_AUTHORITY,
@@ -170,21 +170,9 @@ function onClientStreamClose({ stream }) {
   });
 }
 
-function enable() {
-  dc.subscribe('http2.client.stream.created', onClientStreamCreated);
-  dc.subscribe('http2.client.stream.error', onClientStreamError);
-  dc.subscribe('http2.client.stream.finish', onClientStreamFinish);
-  dc.subscribe('http2.client.stream.close', onClientStreamClose);
-}
-
-function disable() {
-  dc.unsubscribe('http2.client.stream.created', onClientStreamCreated);
-  dc.unsubscribe('http2.client.stream.error', onClientStreamError);
-  dc.unsubscribe('http2.client.stream.finish', onClientStreamFinish);
-  dc.unsubscribe('http2.client.stream.close', onClientStreamClose);
-}
-
-module.exports = {
-  enable,
-  disable,
-};
+module.exports = registerDiagnosticChannels([
+  ['http2.client.stream.created', onClientStreamCreated],
+  ['http2.client.stream.error', onClientStreamError],
+  ['http2.client.stream.finish', onClientStreamFinish],
+  ['http2.client.stream.close', onClientStreamClose],
+]);

filename: lib/internal/inspector/network_undici.js
patch: @@ -10,9 +10,9 @@ const {
   kResourceType,
   getMonotonicTime,
   getNextRequestId,
+  registerDiagnosticChannels,
   sniffMimeType,
 } = require('internal/inspector/network');
-const dc = require('diagnostics_channel');
 const { Network } = require('inspector');
 const { Buffer } = require('buffer');
 
@@ -239,31 +239,14 @@ function onWebSocketClose({ websocket }) {
   });
 }
 
-function enable() {
-  dc.subscribe('undici:request:create', onClientRequestStart);
-  dc.subscribe('undici:request:error', onClientRequestError);
-  dc.subscribe('undici:request:headers', onClientResponseHeaders);
-  dc.subscribe('undici:request:trailers', onClientResponseFinish);
-  dc.subscribe('undici:request:bodyChunkSent', onClientRequestBodyChunkSent);
-  dc.subscribe('undici:request:bodySent', onClientRequestBodySent);
-  dc.subscribe('undici:request:bodyChunkReceived', onClientRequestBodyChunkReceived);
-  dc.subscribe('undici:websocket:open', onWebSocketOpen);
-  dc.subscribe('undici:websocket:close', onWebSocketClose);
-}
-
-function disable() {
-  dc.unsubscribe('undici:request:create', onClientRequestStart);
-  dc.unsubscribe('undici:request:error', onClientRequestError);
-  dc.unsubscribe('undici:request:headers', onClientResponseHeaders);
-  dc.unsubscribe('undici:request:trailers', onClientResponseFinish);
-  dc.unsubscribe('undici:request:bodyChunkSent', onClientRequestBodyChunkSent);
-  dc.unsubscribe('undici:request:bodySent', onClientRequestBodySent);
-  dc.unsubscribe('undici:request:bodyChunkReceived', onClientRequestBodyChunkReceived);
-  dc.unsubscribe('undici:websocket:open', onWebSocketOpen);
-  dc.unsubscribe('undici:websocket:close', onWebSocketClose);
-}
-
-module.exports = {
-  enable,
-  disable,
-};
+module.exports = registerDiagnosticChannels([
+  ['undici:request:create', onClientRequestStart],
+  ['undici:request:error', onClientRequestError],
+  ['undici:request:headers', onClientResponseHeaders],
+  ['undici:request:trailers', onClientResponseFinish],
+  ['undici:request:bodyChunkSent', onClientRequestBodyChunkSent],
+  ['undici:request:bodySent', onClientRequestBodySent],
+  ['undici:request:bodyChunkReceived', onClientRequestBodyChunkReceived],
+  ['undici:websocket:open', onWebSocketOpen],
+  ['undici:websocket:close', onWebSocketClose],
+]);