commit:     6e1ca591c2dacde806a277773d16b603558b04a2
Author:     Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Fri Jul 10 02:40:09 2015 +0000
Commit:     Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Fri Jul 10 02:40:09 2015 +0000
URL:        https://gitweb.gentoo.org/proj/grss.git/commit/?id=6e1ca591

grs/Daemon.py: document.

 grs/Daemon.py | 37 ++++++++++++++++++++++++++++++-------
 1 file changed, 30 insertions(+), 7 deletions(-)

diff --git a/grs/Daemon.py b/grs/Daemon.py
index 15290a5..0d2d988 100644
--- a/grs/Daemon.py
+++ b/grs/Daemon.py
@@ -7,22 +7,31 @@ import sys
 import time
 
 class Daemon:
-    """ doc here
-        more doc
-        Adopted from Sander Marechal's "A simple unix/linux daemon in Python"
+    """ Adopted from Sander Marechal's "A simple unix/linux daemon in Python"
         See: 
http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/
+
+        To use, inherit by a subclass which overrides run() and does all the
+        daemon work.  You start the daemon with
+
+            d = MyDaemon(pidfile, foo='1', bar='2')  # Any number for kwargs 
after pidfile
+            d.start()   # to start the daemon
+            d.restart() # to restart the daemon
+            d.stop()    # to stop the daemon
+
+        Note: This isn't completely general daemon code as it doesn't close 
stdout/stderr.
+        Rather these are redirected to /var/log/grs/grs-daemon-<pid>.err to 
capture any
+        exceptions for debugging.
     """
 
     def __init__(self, pidfile, **kwargs):
+        """ Since this will be used as a super class, we'll accept any **kwargs
+            and insert them to our internal __dict__.
+        """
         self.pidfile = pidfile
         for k in kwargs:
             self.__dict__[k] = kwargs[k]
 
     def daemonize(self):
-        """ doc here
-            more doc
-        """
-
         try:
             pid = os.fork()
             if pid > 0:
@@ -55,6 +64,9 @@ class Daemon:
         sys.stderr.flush()
         os.dup2(se.fileno(), sys.stderr.fileno())
 
+        # Use atexit to remove the pidfile when we shutdown.
+        # No matter where the exit is initiated, eg from Execute.py
+        # we are sure that atexit() will run and delete the pidfile.
         atexit.register(self.delpid)
         with open(self.pidfile,'w') as pf:
             pf.write('%d\n' % os.getpid())
@@ -65,6 +77,10 @@ class Daemon:
 
 
     def start(self):
+        # If there's a pidfile when we try to startup, then either
+        # its stale or we're already running.  If the pidfile is stale,
+        # remove it and startup as usual.  If we're already running,
+        # then don't start a second instance.
         try:
             with open(self.pidfile, 'r') as pf:
                 pid = int(pf.read().strip())
@@ -84,6 +100,13 @@ class Daemon:
 
 
     def stop(self):
+        # Try to open our pidfile and read our pid.  If you have a pid but
+        # there is no process at that pid, then we're not running and all
+        # we have to do is cleanup our stale pidfile.a  If we can't get a
+        # pid from our pidfile, then we've lost the original process.  Either
+        # it crashed or something else killed the pidfile.  We don't know.
+        # Finally if have a valid pid, send it a bunch of SIGTERMS followed
+        # by SIGKILLS just in case.
         try:
             with open(self.pidfile,'r') as pf:
                 pid = int(pf.read().strip())

Reply via email to