commit-gnue
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnue] r7066 - trunk/gnue-common/src/apps


From: johannes
Subject: [gnue] r7066 - trunk/gnue-common/src/apps
Date: Fri, 25 Feb 2005 08:38:35 -0600 (CST)

Author: johannes
Date: 2005-02-25 08:38:32 -0600 (Fri, 25 Feb 2005)
New Revision: 7066

Modified:
   trunk/gnue-common/src/apps/GServerApp.py
Log:
Added a --pidfile option to GServerApp


Modified: trunk/gnue-common/src/apps/GServerApp.py
===================================================================
--- trunk/gnue-common/src/apps/GServerApp.py    2005-02-25 14:00:35 UTC (rev 
7065)
+++ trunk/gnue-common/src/apps/GServerApp.py    2005-02-25 14:38:32 UTC (rev 
7066)
@@ -31,11 +31,20 @@
 #
 
 from gnue.common.apps.GBaseApp import GBaseApp
-from gnue.common.apps import GConfig
+from gnue.common.apps import GConfig, errors
 from gnue.common.apps.GLogger import Logger
-import sys, os
+import sys
+import os
+import os.path
+import signal
 
 
+class ServerRunningError (errors.UserError):
+  def __init__ (self, pid):
+    msg = u_("The server is already running on pid %s") % pid
+    errors.UserError.__init__ (self, msg)
+
+
 # TODO: Implement either multi-threading or asynchronous IO support
 
 class GServerApp(GBaseApp):
@@ -48,10 +57,23 @@
           "this option keeps the server process from forking and detaching "
           "from its controlling terminal.")],
     )
+
+    self.COMMAND_OPTIONS.append (
+        ['pidfile', 'P', 'pidfile', True,
+         '/var/run/gnue/%s.pid' % application or 'gnue', 'pid-file',
+        _("Filename to store the server's process id.")])
+
     GBaseApp.__init__(self, connections, application, defaults)
 
+    if not self.OPTIONS ['foreground']:
+      self.__removeStaleFile ()
+      self.__createPidFile (0)
 
+    signal.signal (signal.SIGTERM, self._terminate)
 
+
+
+
   # This can be overwritten by code necessary
   # for startup.  If overwritten, do not first
   # call the original GServerApp.run(self) as
@@ -63,8 +85,8 @@
   def run(self):
 
     # Fork, if applicable/possible, and send to background
-    if not self.OPTIONS["foreground"]:
-      self.daemonize()
+    if not self.OPTIONS ["foreground"]:
+      self.daemonize ()
 
 
   # Called when a request to shutdown the server is received
@@ -76,7 +98,7 @@
   # Returns 1 if program successfully converted,
   # 0 otherwise.
   #
-  def daemonize(self):
+  def daemonize (self):
 
     # For an overview of what we're doing here,
     # check out the Unix Programmer's FAQ at:
@@ -85,6 +107,8 @@
     # We enclose these actions in try: blocks so that
     # this doesn't fail on non-Unix environments.
 
+    self.__removeStaleFile ()
+
     try:
       # Fork #1
       pid = os.fork()
@@ -121,6 +145,8 @@
       # Fork #2
       pid = os.fork()
       if pid != 0:
+        self.__createPidFile (pid)
+
         sys.exit(0)
     except OSError:
       pass
@@ -143,3 +169,65 @@
     return 1
 
 
+  # ---------------------------------------------------------------------------
+  # Create a new pid file
+  # ---------------------------------------------------------------------------
+
+  def __createPidFile (self, pid):
+    """
+    This function creates a new pid file for the current process.
+
+    @param pid: Process id to store in the pid file
+    """
+
+    pidfile = open (self.OPTIONS ['pidfile'], 'w')
+    pidfile.write ("%s%s" % (pid, os.linesep))
+    pidfile.close ()
+
+
+  # ---------------------------------------------------------------------------
+  # Remove a stale pid file
+  # ---------------------------------------------------------------------------
+
+  def __removeStaleFile (self):
+    """
+    This function checks for a stale pid file. If a file exists, this function
+    raises a ServerRunningError exception if the process is till alive.
+    """
+
+    if os.path.exists (self.OPTIONS ['pidfile']):
+      pidfile = open (self.OPTIONS ['pidfile'], 'r')
+
+      try:
+        oldPid = int (pidfile.readline ().strip ())
+
+        if oldPid:
+          try:
+            os.kill (oldPid, 0)
+
+          except OSError:
+            # remove the stale pid-file
+            os.unlink (self.OPTIONS ['pidfile'])
+
+          else:
+            raise ServerRunningError, oldPid
+
+      finally:
+        pidfile.close ()
+
+
+  # ---------------------------------------------------------------------------
+  # Handle a SIGTERM signal
+  # ---------------------------------------------------------------------------
+
+  def _terminate (self, signal, frame):
+    """
+    This function handles a SIGTERM signal and removes the pid-file if the
+    server is running in the background.
+    """
+
+    if not self.OPTIONS ["foreground"] and \
+        os.path.exists (self.OPTIONS ['pidfile']):
+      os.unlink (self.OPTIONS ['pidfile'])
+
+    sys.exit ()





reply via email to

[Prev in Thread] Current Thread [Next in Thread]