<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Exit MM2 process gracefully?]]></title><description><![CDATA[<p dir="auto">I may be missing it somewhere, but does the core MM2 process call anything to clean up modules and exit gracefully?</p>
<p dir="auto">I was going to add a shutdown function to clean up some child processes started by my module, but was wondering if this functionality is already built into the core node-js app anywhere?  This really only comes into play when restarting the MM process (without restarting the server itself).</p>
<p dir="auto">What I’m looking for would be something similar to the pseudo-code below:</p>
<pre><code class="language-js">process.on('SIGINT', function() {
  modules.forEach( m =&gt; { 
    if (typeof m.exit === "function") {
      m.exit()
    }
  });
  setTimeout(function() { process.exit(0); }, 300 );
);
</code></pre>
]]></description><link>https://forum.magicmirror.builders/topic/4439/exit-mm2-process-gracefully</link><generator>RSS for Node</generator><lastBuildDate>Sun, 19 Apr 2026 20:21:27 GMT</lastBuildDate><atom:link href="https://forum.magicmirror.builders/topic/4439.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 12 Jul 2017 01:48:39 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Exit MM2 process gracefully? on Sun, 15 Oct 2017 23:28:07 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/j.e.f.f" aria-label="Profile: j.e.f.f">@<bdi>j.e.f.f</bdi></a> That could be, I wonder if when Electron starts it somehow removes any SIGINT listeners already created.</p>
<p dir="auto">With respect to running <code>stop()</code> during a MM crash – the main function in <code>js/app.js</code> is still attaching to <code>process.on("SIGINT", ...)</code> just upstream of the individual node_helper files.  If MM crashes I think it should still call the stop() functions unless the node_helper array gets corrupted.  An advantage to cycling through each node_helper would be that you don’t have multiple individual SIGINT listeners that are trying to call a process.exit before the other is done.</p>
]]></description><link>https://forum.magicmirror.builders/post/29619</link><guid isPermaLink="true">https://forum.magicmirror.builders/post/29619</guid><dc:creator><![CDATA[shbatm]]></dc:creator><pubDate>Sun, 15 Oct 2017 23:28:07 GMT</pubDate></item><item><title><![CDATA[Reply to Exit MM2 process gracefully? on Sat, 14 Oct 2017 18:45:10 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/shbatm" aria-label="Profile: shbatm">@<bdi>shbatm</bdi></a> very strange indeed!  The only thing I did differently is I didn’t set up the listener in the <code>start()</code> function, but in the <code>socketNotificationReceived()</code> routine. Maybe the difference is that I’m setting up the listener after Electron has started. The <code>start()</code> function in <code>node_helper.js</code> might execute before Electron starts?</p>
<p dir="auto">I like your <code>stop()</code> function idea but I worry that it won’t be called in the event of an MM crash, in which case anything that should otherwise have run in the <code>stop()</code> routine won’t get called. Listening for <code>SIGINT</code> is a more reliable option in that situation, especially if you have resources that need to be explicitly released.</p>
]]></description><link>https://forum.magicmirror.builders/post/29560</link><guid isPermaLink="true">https://forum.magicmirror.builders/post/29560</guid><dc:creator><![CDATA[j.e.f.f]]></dc:creator><pubDate>Sat, 14 Oct 2017 18:45:10 GMT</pubDate></item><item><title><![CDATA[Reply to Exit MM2 process gracefully? on Sat, 14 Oct 2017 05:17:19 GMT]]></title><description><![CDATA[<p dir="auto">@j-e-f-f, very strange. Mine was in the node-helper file as well, called inside the start function and I also tried it in the core js/app.js file with the same result. As I mentioned, it worked fine for server only and I was pulling my hair out trying to get it to work when running MM normally… Ctrl+C when running <code>npm start</code> and <code>pm2 stop mm</code> with <code>pm2</code> would exit without even writing the console line.</p>
<p dir="auto">Full code that wasn’t working <a href="https://github.com/shbatm/MMM-RTSPStream/blob/wip/node_helper.js#L33" target="_blank" rel="noopener noreferrer nofollow ugc">here</a></p>
<p dir="auto">Working code based on the change request I described <a href="https://github.com/shbatm/MMM-RTSPStream/blob/wip_patch/node_helper.js#L33" target="_blank" rel="noopener noreferrer nofollow ugc">here</a></p>
<p dir="auto">Thank you for the help, I’m going to chalk it up to a fluke that I’ve spent too much time investigating and now have a work around. It’ll be nice to have a standard clean-up method incorporated in the main code anyways.</p>
]]></description><link>https://forum.magicmirror.builders/post/29531</link><guid isPermaLink="true">https://forum.magicmirror.builders/post/29531</guid><dc:creator><![CDATA[shbatm]]></dc:creator><pubDate>Sat, 14 Oct 2017 05:17:19 GMT</pubDate></item><item><title><![CDATA[Reply to Exit MM2 process gracefully? on Fri, 13 Oct 2017 22:06:13 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/shbatm" aria-label="Profile: shbatm">@<bdi>shbatm</bdi></a> I have that code working with Electron running. I’m running it on the server side in node_helper.js, not in he browser-side main module file. Maybe that’s the difference?</p>
]]></description><link>https://forum.magicmirror.builders/post/29521</link><guid isPermaLink="true">https://forum.magicmirror.builders/post/29521</guid><dc:creator><![CDATA[j.e.f.f]]></dc:creator><pubDate>Fri, 13 Oct 2017 22:06:13 GMT</pubDate></item><item><title><![CDATA[Reply to Exit MM2 process gracefully? on Fri, 13 Oct 2017 21:47:22 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/j.e.f.f" aria-label="Profile: j.e.f.f">@<bdi>j.e.f.f</bdi></a> Just curious, are you running MM as <code>server-only</code> or with Electron (<code>npm start</code>)?   My problem is I used almost exactly the same snippet you have and it was completely ignored when using Electron; however, it worked fine when using <code>server-only</code> mode.  I did some research and found that the Electron browser intercepts the exit commands and needs an <code>app.on("before-quit"...</code> command, but I couldn’t override this from a module.</p>
<p dir="auto">I ended up making a tweak to the core and a pull request to work around this:<br />
<a href="https://github.com/MichMich/MagicMirror/pull/1058" target="_blank" rel="noopener noreferrer nofollow ugc">https://github.com/MichMich/MagicMirror/pull/1058</a></p>
<p dir="auto">If this gets incorporated then all you’d need in your <code>node_helper.js</code> is a <code>stop()</code> function:</p>
<pre><code class="language-javascript">stop: function() { 
  console.log("[MMM-MyWink] Cleaning Up");
  self.pubnub.removeListener(self.pnListener);
  self.pubnub.unsubscribeAll();
} 
</code></pre>
]]></description><link>https://forum.magicmirror.builders/post/29520</link><guid isPermaLink="true">https://forum.magicmirror.builders/post/29520</guid><dc:creator><![CDATA[shbatm]]></dc:creator><pubDate>Fri, 13 Oct 2017 21:47:22 GMT</pubDate></item><item><title><![CDATA[Reply to Exit MM2 process gracefully? on Fri, 13 Oct 2017 20:08:48 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/shbatm" aria-label="Profile: shbatm">@<bdi>shbatm</bdi></a> what problems did you run in to?  I’m using <code>process.on('SIGINT'...)</code> in two of my modules and they both get called called on MM exit.</p>
<p dir="auto">Here’s an example from my <code>MMM-MyWink</code> module:</p>
<pre><code>socketNotificationReceived: function(notification, payload){

    var self = this;

    if (notification === 'MMM-MYWINK-GET-INITIAL-STATUS') {

      // ... edited for brevity

      } else {

        this.config = payload;

        //log into Wink account and set up subscriptions
        this.initialize();

        //set up some cleanup on application exit
        process.on('SIGINT', function () {  
          console.log("[MMM-MyWink] Cleaning Up");
          self.pubnub.removeListener(self.pnListener);
          self.pubnub.unsubscribeAll();
          process.exit();
        });

      } 


    }
  },
</code></pre>
<p dir="auto">Full code here:<br />
<a href="https://github.com/jclarke0000/MMM-MyWink/blob/master/node_helper.js" target="_blank" rel="noopener noreferrer nofollow ugc">https://github.com/jclarke0000/MMM-MyWink/blob/master/node_helper.js</a></p>
]]></description><link>https://forum.magicmirror.builders/post/29510</link><guid isPermaLink="true">https://forum.magicmirror.builders/post/29510</guid><dc:creator><![CDATA[j.e.f.f]]></dc:creator><pubDate>Fri, 13 Oct 2017 20:08:48 GMT</pubDate></item><item><title><![CDATA[Reply to Exit MM2 process gracefully? on Fri, 13 Oct 2017 18:57:06 GMT]]></title><description><![CDATA[<p dir="auto">I ended up opening an issue related to this on GitHub here: <a href="https://github.com/MichMich/MagicMirror/issues/1056" target="_blank" rel="noopener noreferrer nofollow ugc">#1056</a>. I was trying to implement the method @j-e-f-f suggested, but when using Electron, it ignores the call to <code>process.on('SIGINT'...)</code>.</p>
<p dir="auto">What I am suggesting, in case anyone else developing a module needs this: allow module developers to implement a <code>stop: function() { }</code> in their <code>node_helper.js</code> file that performs any cleanup required.  When exiting, the MM app will call this function, if it exists, and each module can gracefully exit on it’s own.</p>
<p dir="auto">There is a working example of this here: <a href="https://github.com/shbatm/MagicMirror/commit/9935d2fccb4206c2949b43cc118aad6789303f12" target="_blank" rel="noopener noreferrer nofollow ugc">shbatm/MagicMirror@9935d2f</a></p>
]]></description><link>https://forum.magicmirror.builders/post/29503</link><guid isPermaLink="true">https://forum.magicmirror.builders/post/29503</guid><dc:creator><![CDATA[shbatm]]></dc:creator><pubDate>Fri, 13 Oct 2017 18:57:06 GMT</pubDate></item><item><title><![CDATA[Reply to Exit MM2 process gracefully? on Wed, 12 Jul 2017 03:05:23 GMT]]></title><description><![CDATA[<p dir="auto">@j-e-f-f Thanks for the quick feedback!</p>
<p dir="auto">I was assuming I would need the cleanup routine in my module, I was just wondering if there was some routine in the core code that already listened for SIGINT and then called each module’s cleanup function (if there was one)–like it does with each node_helper.js’s start function–that way I would just have to add a function instead of add multiple SIGINT handlers (one in each module).</p>
<p dir="auto">It’s probably a niche requirement and it’s easy enough to add them for each module that needs one.  Just curious if it existed, or was maybe worth adding.</p>
]]></description><link>https://forum.magicmirror.builders/post/25247</link><guid isPermaLink="true">https://forum.magicmirror.builders/post/25247</guid><dc:creator><![CDATA[shbatm]]></dc:creator><pubDate>Wed, 12 Jul 2017 03:05:23 GMT</pubDate></item><item><title><![CDATA[Reply to Exit MM2 process gracefully? on Wed, 12 Jul 2017 02:30:53 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/shbatm" aria-label="Profile: shbatm">@<bdi>shbatm</bdi></a> Even if it does run some kind of cleanup routine when it closes, pm2 can’t know everything about what MagicMirror and the modules are doing, so writing a shutdown routine into your module can’t hurt.</p>
<p dir="auto">I’ve used the PubNub API in a couple of my modules and I run a routine on SIGINT to remove listeners and subscriptions. Pm2’s exit might take care of nullifying these or it might not, but with by writing the exit routine I can be sure these are taken care of.</p>
]]></description><link>https://forum.magicmirror.builders/post/25246</link><guid isPermaLink="true">https://forum.magicmirror.builders/post/25246</guid><dc:creator><![CDATA[j.e.f.f]]></dc:creator><pubDate>Wed, 12 Jul 2017 02:30:53 GMT</pubDate></item></channel></rss>