[Twisted-Python] supporting start/stop/restart behavior
Clark C. Evans
cce at clarkevans.com
Wed Mar 19 20:58:43 EST 2003
First, before I get started, I'd like to say that I'm a new
fan of twistd, it is quite nice tool, and I think everyone
should use it. However, that being said, what it misses,
IMHO, is a simple interface to stop and restart. Also, it
lacks a nice way to be embedded within a python script
so that the __main__ == __name__ hack runs the file properly.
Anyway, what I'd like... is to take my arbitrary "test.py" file,
let's say an application as simple as...
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('.')))
And add these three lines of code to make it runnable...
if '__main__' == __name__:
from twisted.scripts.twistd import runDirect
runDirect(save=1)
In this way, the following commands 'just 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
And, even twistd options can be included...
python test.py --quiet start
python test.py --quiet
What this involves is two things:
1. Refactoring runApp to remove a hunk of code which
runs os.kill on a pid found in the given pidfile.
This is moved to another function, killApp, which
takes two arguments, config and signal. From the
runApp the code then calls killApp(config, signal=0)
2. Adding a new function, runDirect which does
several things:
a. takes 'start', 'stop', and 'restart' as the last
argument on the command line, if none of these
are found, then the application is assumed to be
run interactively (nodaemon); and
b. it adds --python <filename> where filename is the
name of the current python file (argv[0]), further,
it gives a direct option in the function arguments
to not save the tap file (saving a tap file is
not always useful, and as an argument it is hard
to miss); and
c. if stop or restart are chosen, then this kills the
current process using the given pidfile (which defaults
to twistd.pid in the current directory) through
killApp(signal=SIGTERM)
d. unless stop is chosen, the app is then started using
the configuration options as parsed (and modified via
the --python option)
This function could be broken into the start/stop/restart
behavior from the --python option; but I don't have this
requirement and people in the IRC list didn't seem to think
that either of these two functions are useful.
Anyway, I'm posting to this list beacuse I think the way in
which twistd is used isn't obvious... i.e. the primary way
you'd use it with a python source file is an option buried
among many others.
I raised this change on the IRC list, and the primary argument
against the above was that it is out-of-scope; in other words,
one could write a shell script to do the same. I think this
is a bad argument beacuse _all_ of twistd could be done in
a shell script. For example, if you ask D. J. Bernstein, he'd
say that none of this deamon / logging behavior needs to be
in an application, and this is why he has his 'daemontools'.
So, the argument shouldn't be _can_ this be done externally,
of course it can. The question is does it make sence to
standardize on particular ways of using twisted so that everyone
doesn't have their own approach, to logging, etc. I feel that
this comes all the way down to Twisted having a simple way
to start/stop/restart a server without having to rely upon
external, non-Twisted scripts.
At the very least, I'd like the killApp refactor to be
accepted, as I'd rather not have to duplicate killApp
code within a private/sandbox copy of runDirect.
Best,
Clark
More information about the Twisted-Python
mailing list