From c1aa10323db0ada94137c56001ec307f4825ee2f Mon Sep 17 00:00:00 2001 From: Gabriel Schulhof Date: Wed, 26 Jul 2023 12:26:39 -0700 Subject: [PATCH] diagnostics_channel: handle last subscriber removal When iterating over diagnostics channel subscribers, assume their count is zero if the list of subscribers becomes undefined, because there may be only one subscriber which may unsubscribe itself as part of its onMessage handler. --- lib/diagnostics_channel.js | 2 +- .../test-diagnostics-channel-sync-unsubscribe.js | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 test/parallel/test-diagnostics-channel-sync-unsubscribe.js diff --git a/lib/diagnostics_channel.js b/lib/diagnostics_channel.js index b399c1e2f87ad3..dae0e930a395e9 100644 --- a/lib/diagnostics_channel.js +++ b/lib/diagnostics_channel.js @@ -136,7 +136,7 @@ class ActiveChannel { } publish(data) { - for (let i = 0; i < this._subscribers.length; i++) { + for (let i = 0; i < (this._subscribers?.length || 0); i++) { try { const onMessage = this._subscribers[i]; onMessage(data, this.name); diff --git a/test/parallel/test-diagnostics-channel-sync-unsubscribe.js b/test/parallel/test-diagnostics-channel-sync-unsubscribe.js new file mode 100644 index 00000000000000..87bf44249f5fc4 --- /dev/null +++ b/test/parallel/test-diagnostics-channel-sync-unsubscribe.js @@ -0,0 +1,14 @@ +'use strict'; + +const common = require('../common'); +const dc = require('node:diagnostics_channel'); + +const channel_name = 'test:channel'; +const published_data = 'some message'; + +const onMessageHandler = common.mustCall(() => dc.unsubscribe(channel_name, onMessageHandler)); + +dc.subscribe(channel_name, onMessageHandler); + +// This must not throw. +dc.channel(channel_name).publish(published_data);