1. Eric Larson
  2. AutoRebuild

Commits

Eric Larson  committed 7e82a19 Draft

Handle restarts by using the pid when the Popen object is gone after an exec.

  • Participants
  • Parent commits 6934815
  • Branches default

Comments (0)

Files changed (1)

File autorebuild.py

View file
 import glob
 import subprocess
 import shlex
+import signal
 
 from cherrypy.process.plugins import Autoreloader
 from cherrypy.process.plugins import SimplePlugin
         self.cmd = None
         self.args = []
         self.kw = {}
+        self.pid = None
 
     def start(self):
-        if self.cmd:
+        """
+        Start our process and store our Popen object and pid.
+        """
+        if self.cmd and not self.pid:
+            # We can use a list or a string for the command.
             if isinstance(self.cmd, basestring):
                 self.cmd = shlex.split(self.cmd)
+
+            # Start our process
             self.proc = subprocess.Popen(self.cmd,
                                          *self.args,
                                          **self.kw)
+            # Store the pid separately. When cherrypy restarts it does
+            # an exec which kills our Popen instance. We can use the
+            # pid to stop the process safely.
+            self.pid = self.proc.pid
+
+    def kill(self):
+        """
+        Stop the process via the Popen object or pid.
+        """
+        if self.proc and self.proc.poll():
+            # We trust the process will end happily with a
+            # SIGTERM. Might need a hook to help things along if it
+            # doesn't stop nicely.
+            self.proc.terminate()
+            self.proc.wait()
+        elif self.pid:
+            # We have been restarted which means our proc object is
+            # gone. We can still use our pid and os.kill directly.
+            os.kill(self.pid, signal.SIGTERM)
 
     def stop(self):
-        if self.proc and self.proc.poll():
-            self.proc.terminate()
-            self.proc.wait()
+        self.kill()
 
 
 if __name__ == '__main__':