[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