MagicMirror Forum
    • Recent
    • Tags
    • Unsolved
    • Solved
    • MagicMirror² Repository
    • Documentation
    • 3rd-Party-Modules
    • Donate
    • Discord
    • Register
    • Login
    A New Chapter for MagicMirror: The Community Takes the Lead
    Read the statement by Michael Teeuw here.

    Exit MM2 process gracefully?

    Scheduled Pinned Locked Moved Bug Hunt
    10 Posts 2 Posters 4.0k Views 2 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • S Offline
      shbatm Module Developer
      last edited by

      I ended up opening an issue related to this on GitHub here: #1056. I was trying to implement the method @j-e-f-f suggested, but when using Electron, it ignores the call to process.on('SIGINT'...).

      What I am suggesting, in case anyone else developing a module needs this: allow module developers to implement a stop: function() { } in their node_helper.js 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.

      There is a working example of this here: shbatm/MagicMirror@9935d2f

      J 1 Reply Last reply Reply Quote 0
      • J Offline
        j.e.f.f Project Sponsor Module Developer @shbatm
        last edited by

        @shbatm what problems did you run in to? I’m using process.on('SIGINT'...) in two of my modules and they both get called called on MM exit.

        Here’s an example from my MMM-MyWink module:

        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();
                });
        
              } 
        
        
            }
          },
        

        Full code here:
        https://github.com/jclarke0000/MMM-MyWink/blob/master/node_helper.js

        S 1 Reply Last reply Reply Quote 0
        • S Offline
          shbatm Module Developer @j.e.f.f
          last edited by

          @j.e.f.f Just curious, are you running MM as server-only or with Electron (npm start)? 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 server-only mode. I did some research and found that the Electron browser intercepts the exit commands and needs an app.on("before-quit"... command, but I couldn’t override this from a module.

          I ended up making a tweak to the core and a pull request to work around this:
          https://github.com/MichMich/MagicMirror/pull/1058

          If this gets incorporated then all you’d need in your node_helper.js is a stop() function:

          stop: function() { 
            console.log("[MMM-MyWink] Cleaning Up");
            self.pubnub.removeListener(self.pnListener);
            self.pubnub.unsubscribeAll();
          } 
          
          J 1 Reply Last reply Reply Quote 0
          • J Offline
            j.e.f.f Project Sponsor Module Developer @shbatm
            last edited by

            @shbatm 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?

            1 Reply Last reply Reply Quote 0
            • S Offline
              shbatm Module Developer
              last edited by

              @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 npm start and pm2 stop mm with pm2 would exit without even writing the console line.

              Full code that wasn’t working here

              Working code based on the change request I described here

              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.

              J 1 Reply Last reply Reply Quote 0
              • J Offline
                j.e.f.f Project Sponsor Module Developer @shbatm
                last edited by

                @shbatm very strange indeed! The only thing I did differently is I didn’t set up the listener in the start() function, but in the socketNotificationReceived() routine. Maybe the difference is that I’m setting up the listener after Electron has started. The start() function in node_helper.js might execute before Electron starts?

                I like your stop() 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 stop() routine won’t get called. Listening for SIGINT is a more reliable option in that situation, especially if you have resources that need to be explicitly released.

                S 1 Reply Last reply Reply Quote 0
                • S Offline
                  shbatm Module Developer @j.e.f.f
                  last edited by

                  @j.e.f.f That could be, I wonder if when Electron starts it somehow removes any SIGINT listeners already created.

                  With respect to running stop() during a MM crash – the main function in js/app.js is still attaching to process.on("SIGINT", ...) 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.

                  1 Reply Last reply Reply Quote 0
                  • 1 / 1
                  • First post
                    Last post
                  Enjoying MagicMirror? Please consider a donation!
                  MagicMirror created by Michael Teeuw.
                  Forum managed by Sam, technical setup by Karsten.
                  This forum is using NodeBB as its core | Contributors
                  Contact | Privacy Policy