[Twisted-Python] Re: supporting start/stop/restart behavior

Clark C. Evans cce at clarkevans.com
Wed Mar 19 20:59:56 EST 2003


--- twistd.py.orig	Wed Mar 19 16:21:46 2003
+++ twistd.py	Wed Mar 19 20:19:15 2003
@@ -211,6 +211,31 @@
     import pdb
     pdb.set_trace()
 
+def killApp(config, signal = 0):
+    if os.path.exists(config['pidfile']):
+        try:
+            pid = int(open(config['pidfile']).read())
+        except ValueError:
+            sys.exit('Pidfile %s contains non numeric value' % config['pidfile'])
+
+        try:
+            os.kill(pid, signal)
+        except OSError, why:
+            if why[0] == errno.ESRCH:
+                # The pid doesnt exists.
+                if not config['quiet']:
+                    print 'Removing stale pidfile %s' % config['pidfile']
+                    os.remove(config['pidfile'])
+            else:
+                sys.exit('Can\'t check status of PID %s from pidfile %s: %s' % (pid, config['pidfile'], why[1]))
+        else:
+            if not(signal):
+                sys.exit("""\
+Another twistd server is running, PID %s\n
+This could either be a previously started instance of your application or a
+different application entirely. To start a new one, either run it in some other
+directory, or use my --pidfile and --logfile parameters to avoid clashes.
+""" %  pid)
 
 def runApp(config):
     global initRun
@@ -248,29 +273,7 @@
     # This will fix up accidental function definitions in evaluation spaces
     # and the like.
     initRun = 0
-    if os.path.exists(config['pidfile']):
-        try:
-            pid = int(open(config['pidfile']).read())
-        except ValueError:
-            sys.exit('Pidfile %s contains non numeric value' % config['pidfile'])
-
-        try:
-            os.kill(pid, 0)
-        except OSError, why:
-            if why[0] == errno.ESRCH:
-                # The pid doesnt exists.
-                if not config['quiet']:
-                    print 'Removing stale pidfile %s' % config['pidfile']
-                    os.remove(config['pidfile'])
-            else:
-                sys.exit('Can\'t check status of PID %s from pidfile %s: %s' % (pid, config['pidfile'], why[1]))
-        else:
-            sys.exit("""\
-Another twistd server is running, PID %s\n
-This could either be a previously started instance of your application or a
-different application entirely. To start a new one, either run it in some other
-directory, or use my --pidfile and --logfile parameters to avoid clashes.
-""" %  pid)
+    killApp(config)
 
     if config['logfile'] == '-':
         if not config['nodaemon']:
@@ -472,3 +475,66 @@
         os._exit(1)
 
     runApp(config)
+
+def runDirect(save=1):
+    """ run directly from python file
+
+        You can use this function to include start/stop/restart
+        functionality directly from your twisted application.
+        Following is example code, let us call it test.py,
+
+            if '__main__' == __name__:
+                # run this before twisted.internet.reactor is imported
+                from twisted.scripts.twistd import runDirect
+                runDirect(save=1)
+
+            from twisted.internet import app
+            from twisted.web.server import Site
+            from twisted.web.static import File
+            
+            application = app.Application('test')
+            application.listenTCP(8080, Site(File('.')))
+            
+
+        Given this code, the following will now work,
+           python test.py          # runs the app directly (no daemon)
+           python test.py start    # runs the app as a deamon
+           python test.py stop     # stops the app as a deamon
+           python test.py restart  # restarts the app as a deamon 
+       
+        Options can be included as well, for example, 
+           python test.py --quiet start    # deamon
+           python test.py --quiet          # no deamon
+    """
+    from sys import argv, exit
+    config = ServerOptions()
+    config.synopsis = "Usage: %s [options] start|stop|restart" % argv[0]
+    bStop = 0; bStart = 1; bDaemon = 0
+    cmd = argv[-1]
+    if cmd in ('start', 'stop', 'restart'):
+        argv.pop()
+        bDaemon = 1
+        if 'restart' == cmd:
+            bStop = 1
+        if 'stop' == cmd:
+            bStart = 0
+            bStop = 1
+    try:
+        config.parseOptions()
+    except usage.error, ue:
+        print config.opt_help()
+        exit(1)
+    if bStop:
+        from signal import SIGTERM
+        from os.path import exists
+        from time import sleep
+        killApp(config, SIGTERM)
+        nWait = 0  # processes do not die instantly
+        while exists(config['pidfile']) and nWait < 20:
+            sleep(.1)
+            nWait += 1
+    if bStart:
+        if not save:    config["no_save"] = 1
+        if not bDaemon: config['nodaemon'] = 1
+        config["python"] = argv[0]
+        runApp(config)




More information about the Twisted-Python mailing list