[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

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

     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.



More information about the Twisted-Python mailing list