MagicMirrorOrg / MagicMirror

MagicMirror² is an open source modular smart mirror platform. With a growing list of installable modules, the MagicMirror² allows you to convert your hallway or bathroom mirror into your personal assistant.
http://magicmirror.builders
MIT License
19.65k stars 4.18k forks source link

Multiple Instances of Node Helper running for a single module #3502

Open taylornoss opened 1 month ago

taylornoss commented 1 month ago

I found a bug in MagicMirror

Platform: Electron version 31.1.0 running on Windows (reproducible on both Windows 10 and Windows 11)

Node Version: v20.15.1

MagicMirror² Version: 2.28.0

Description: There are a couple of modules my mirror that are repeated, to be configured with different module level settings. I'm seeing instances of multiple node helpers being created for the repeated modules, which is leading to unnecessary noise in communication between the modules and the node helpers.

It's my understanding that there should only be one instance of a node helper per module type. From the Module Development Documentation:

For every module type, only one node helper instance will be created. For example: if your MagicMirror uses two calendar modules, there will be only one calendar node helper instantiated.

Here's the output from the command line with two instances of the MMM-GoogleCalendar module in the config file

[2024-07-12 17:59:28.017] [LOG]   Starting MagicMirror: v2.28.0
[2024-07-12 17:59:28.072] [LOG]   Loading config ...
[2024-07-12 17:59:28.073] [LOG]   config template file not exists, no envsubst
[2024-07-12 17:59:28.074] [LOG]   Loading module helpers ...
[2024-07-12 17:59:28.075] [LOG]   No helper found for module: alert.
[2024-07-12 17:59:28.077] [LOG]   Initializing new module helper ...
[2024-07-12 17:59:28.078] [LOG]   Module helper loaded: updatenotification
[2024-07-12 17:59:28.078] [LOG]   No helper found for module: clock.
[2024-07-12 17:59:28.683] [LOG]   Initializing new module helper ...
[2024-07-12 17:59:28.683] [LOG]   Module helper loaded: MMM-GoogleCalendar
[2024-07-12 17:59:28.684] [LOG]   Initializing new module helper ...
[2024-07-12 17:59:28.684] [LOG]   Module helper loaded: MMM-GoogleCalendar

Each instance of the module seems to be loading it's own version of the node helper.

Reading through the initialization code, I'm not seeing anything preventing duplicate node helpers from being started. I think the answer might be as simple as removing duplicates from the module list before loading them? We could just use a Set to remove any duplicates from the modules array:

// MagicMirror -> js -> app.js
// this.start function, line #272

// change 
await loadModules(modules);
// to 
let unique = [...new Set(modules)];
await loadModules(unique);

Or prevent duplicates from being added to the array further upstream, but this would just be a one-liner fix.

bbf commented 1 month ago

I encountered the same bug while trying to understand why a module was not working properly and there a broadcast storm of WS messages. Is this a regression from the original behavior or was it always like this?

bbf commented 1 month ago

I found the issue: https://github.com/MagicMirrorOrg/MagicMirror/commit/53fc814ff8ad5ad5f8289037c692bf28daa4378a#r144318440

sdetweil commented 1 month ago

try my fix, see https://forum.magicmirror.builders/topic/18863/odd-module-load-behaviour-after-upgrading-to-2-28/4?_=1721215049862

sdetweil commented 1 month ago

we changed to allowing an async process from mode_helper.start but there is a race condition where we haven't completed the first and allow more.