← Back to team overview

ubuntu-accomplishments-contributors team mailing list archive

Daemon launcher

 

Hello everyone,

I have another idea concerning the daemon that requires discussion.

It came to me when I was thinking about #1022129 (Another twistd
server is running, PID 1915), so those of you who are subscribed to
bugs may be already familiar with it - but I'll expand it with some
more details.

Basically what I want to suggest is that we had a more elegant way of
starting/stopping the daemon. Currently we start the daemon with:
     twistd -noy /usr/bin/accomplishments-daemon
but it actually should be:
     twistd -y /usr/bin/accomplishments-daemon
--logfile=~/.cache/accomplishments/logs/daemon.log
--pidfile=/some/other/path

It goes without saying that it is not very elegant, and requires to
remember all the arguments. But there is more, consider how we stop
it:
     killall -9 twistd

The way we stop the daemon has always bothered me very much, but I
hadn't yet a chance to say it out loud. How can we assume that the
only twistd process in the system is our accomplishments daemon? What
if there are others? Twisted is a relatively popular framework, I have
seen many apps written in it, and we do not want to stop all these
services just to stop our daemon. That's really nasty!

I imagine an ideal way to start the daemon would look like this:
     accomplishments-daemon
and stopping it should be like:
     accomplishments-daemon --stop

At the moment, the first is probably possible. This is because the
accomplishments-daemon script has following shebang:
"#!/usr/bin/twistd -y". It may seem like a wise approach, but it's
not. There are several significant problems with starting the daemon
using such shebang:
  - It does not store the log file in the place we want it to be, and
similarly the pidfile gets lost.
     - Adding arguments for logfile/pidfile in the shebang will cause
crashes in case the cache directory does not exist, and we have no
chance of creating it when needed, for twistd needs the directory
before any piece of our code gets executed.
  - Daemon started this way cannot be killed easily, as it's process
is not `twistd' but `env' in such case, so it has to be searched for
manually.

Therefore, the daemon launcher should be a bit wiser. What if we made
the accomplishment-daemon script *both the launcher and twistd
application at once*? It would run in two modes - one when started
directly (accomplishments-daemon), and another when started via twistd
(twistd -y accomplishments-daemon blah blah blah)? Determining how it
was started is quite simple, and gives us following benefits:
  - When run via twistd, the script would behave just as it does now,
no changes at all here.
  - When run directly, it would:
    - Delete the pidfile if it's still kept (that fixes the bug I've
mentioned, #1022129)
    - Create cache directories before twistd uses them (there was a
bug report for that too, can't find it though)
    - Store the pidfile in a known location to track daemon status
    - Take care of passing correct arguments to twistd (this is done
now either by the viewer or by us in command-line)
    - And eventually, run twisted with these args on itself (as the
accomplishments-daemon would be both a launcher script and twistd
application)
    - If run with --stop argument, it would read the pidfile, and kill
the daemon process (if present)
    - More useful arguments are possible:
      -  --restart - stops and starts again
      -  --status - tells whether the daemon is running
      -  --reload - asks the running daemon to reload the
accomplishments database, allowing to test new accomplishments without
restarting the daemon
      - and possibly even even more options.

Concluding, such solution would provide much better user experience
with manually starting/stopping the daemon, and it also gives us much
more control of how the daemon is started.

Thoughts, ideas? Comments welcome :)

Rafał Cieślak


Follow ups