T
Thomas Courbon
Hello there,
I currently have a little project which involve the writing of a
server that launch tasks when requested by the user (through a web
interface for instance).
I would like to turn my server script into a Linux/Unix daemon
(launched at boot time by init, dunno if that matter) using the nice
python-daemon package by Ben Finley et al (http://pypi.python.org/pypi/
python-daemon/). This package comes with a class DaemonRunner that
seems to fit almost exactly my need but I still have some
interrogation.
My main class looks like the following:
class SIGTERM_Received(Exception):
pass
class MyDaemon(object):
def __init__(self):
self.pidfile = '/path/to/the/file'
self.pidfile_timeout = 5
self.stdin_path = None
self.stdout_path = None
self.stderr_path = None
def run(self):
self.init()
self.main_loop()
self.terminate()
def init(self):
#doing some initialisation here eg: database connection, logging,
connection establishing and such...
signal.signal (signal.SIGTERM, lambda: raise SIGTERM_Received()) #
used to interrupt the connection listening loop
def main_loop(self):
#This is the "server" loop
try:
while True:
rcv = self.some_connection.receive() # this may hang until
something was written into the connection by a client.
# do something with rcv that involving processes spawning,
database interaction and so on...
except SIGTERM_Received:
return
def terminate(self):
#some clean up like connection closing and child processes
joining.
pass
And this is the script I intend to drop into /etc/rc.d (for an
Archlinux-style initd):
#! /usr/bin/python
from daemon.runner import DaemonRunner
from foo import MyDaemon
daemon_runner = DaemonRunner(MyDaemon())
daemon_runner.parse_args()
daemon_runner.do_action()
The DaemonRunner class expects my class to have stdin_path,
stdout_path, stderr_path attributes and after reading the code it
seems they have to be valid paths. Is that ok for a Daemon to redirect
those stream to /dev/null for example ? I would prefer to alter the
DaemonRunner class to accept None as value since DaemonContext, the
underlying class, seems to accept None for those parameters.
Also, the DaemonRunner use os.kill(pid, signal.SIGTERM) to stop the
daemon. I wonder if with my signal handling I'll be able to terminate
correctly the daemon (joining children, flushing buffers, closing
connections...). If that's relevant, the connection I use is a
Listener/Client connection from the standard multiprocessing module.
I'm quite neophyte in Unix daemon programming so please forgive me if
my question are obvious.
Thank for reading,
Thomas
I currently have a little project which involve the writing of a
server that launch tasks when requested by the user (through a web
interface for instance).
I would like to turn my server script into a Linux/Unix daemon
(launched at boot time by init, dunno if that matter) using the nice
python-daemon package by Ben Finley et al (http://pypi.python.org/pypi/
python-daemon/). This package comes with a class DaemonRunner that
seems to fit almost exactly my need but I still have some
interrogation.
My main class looks like the following:
class SIGTERM_Received(Exception):
pass
class MyDaemon(object):
def __init__(self):
self.pidfile = '/path/to/the/file'
self.pidfile_timeout = 5
self.stdin_path = None
self.stdout_path = None
self.stderr_path = None
def run(self):
self.init()
self.main_loop()
self.terminate()
def init(self):
#doing some initialisation here eg: database connection, logging,
connection establishing and such...
signal.signal (signal.SIGTERM, lambda: raise SIGTERM_Received()) #
used to interrupt the connection listening loop
def main_loop(self):
#This is the "server" loop
try:
while True:
rcv = self.some_connection.receive() # this may hang until
something was written into the connection by a client.
# do something with rcv that involving processes spawning,
database interaction and so on...
except SIGTERM_Received:
return
def terminate(self):
#some clean up like connection closing and child processes
joining.
pass
And this is the script I intend to drop into /etc/rc.d (for an
Archlinux-style initd):
#! /usr/bin/python
from daemon.runner import DaemonRunner
from foo import MyDaemon
daemon_runner = DaemonRunner(MyDaemon())
daemon_runner.parse_args()
daemon_runner.do_action()
The DaemonRunner class expects my class to have stdin_path,
stdout_path, stderr_path attributes and after reading the code it
seems they have to be valid paths. Is that ok for a Daemon to redirect
those stream to /dev/null for example ? I would prefer to alter the
DaemonRunner class to accept None as value since DaemonContext, the
underlying class, seems to accept None for those parameters.
Also, the DaemonRunner use os.kill(pid, signal.SIGTERM) to stop the
daemon. I wonder if with my signal handling I'll be able to terminate
correctly the daemon (joining children, flushing buffers, closing
connections...). If that's relevant, the connection I use is a
Listener/Client connection from the standard multiprocessing module.
I'm quite neophyte in Unix daemon programming so please forgive me if
my question are obvious.
Thank for reading,
Thomas