1

My understanding of Python's daemon module is that I can have a script that does stuff, spawns a daemon, and continues to do stuff. When the script finishes the daemon should hang around. Yes?

But that's not happening...

I have a python script that uses curses to manage a whole bunch of scripts and functions. It works wonderfully except when I use the script to spawn a daemon.

Now a daemon in this application is represented by a class. For example:

class TestDaemon(DaemonBase):
    def __init__(self,stuff):
        logger.debug("TestDaemon.__init__()")

    def run(self):
        logger.debug("TestDaemon entering loop")
        while True:
            pass

    def cleanup(self):
        super(TestDaemon,self).cleanup()
        logger.debug("TestDaemon.cleanup()")

    def load_config(self):
        super(TestDaemon,self).load_config()
        logger.debug("TestDaemon.load_config()")

And the daemon is launched with a function like:

def launch(*args,**kwargs):
    import daemon
    import lockfile
    import signal
    import os

    oDaemon = TestDaemon(stuff)

    context = daemon.DaemonContext(
        working_directory=os.path.join(os.getcwd(),sAppName),
        umask=0o077, #chmod mode = 777 minus umask. Only current user has access
        pidfile=lockfile.FileLock('/home/sheena/.daemons/{0}__{1}.pid'.format(sAppName,sProcessName)),
    )

    context.signal_map = {
        signal.SIGTERM: oDaemon.cleanup,   #cleanup
        signal.SIGHUP: 'terminate',
        signal.SIGUSR1: oDaemon.load_config,   #reload config
    }


    logger.debug("launching daemon")

    with context:
        oDaemon.run()

    logger.debug("daemon launched")

The program gets as far as logging "launching daemon".

After this point, everything exits and the daemon doesn't run.

Any ideas why this would happen?

There is no evidence of exceptions - exceptions are set to be logged but there are none.

Question: Any ideas why this could be happening?

Stuff I've tried:

  • If I have oDaemon.run() in a try block it fails in exactly the same way
  • I assumed maybe the context is set up wrong so replaced with context with with daemon.DaemonContext(). Same problem
  • I replaced:

    with context: oDaemon.run()

with

def run():
    while True:
        pass
with context:
    run()

and the main program still exited prematurely but at least it spawned a daemon so I assume it doesn't like the way I put stuff in a class...

Josh Kelley
  • 56,064
  • 19
  • 146
  • 246
Sheena
  • 15,590
  • 14
  • 75
  • 113
  • There's no code here that actually spawns a new process. – Jussi Kukkonen Feb 26 '14 at 13:39
  • 1
    @jku: Are you sure: I'm using https://pypi.python.org/pypi/python-daemon/ – Sheena Feb 26 '14 at 14:47
  • 1
    Daemons are devilishly (sorry :) hard to debug. If you get stuck, consider creating a normal, non-daemonized Python program then externally daemonize it using supervisord or a similar utility. This can save a lot of headaches. – Chris Johnson Feb 26 '14 at 15:03

1 Answers1

0

We don't know anything about this DaemonBase class, but this:

with context:
    oDaemon.run()

is a blocking call, cause you have infinite loop in run(). That is why your program cannot continue further.

Where is the code for starting actual daemon process?

pajton
  • 15,828
  • 8
  • 54
  • 65
  • It's more than just a blocking call - it's causing the main process to terminate. The child process is supposed to execute run but doesn't. Unfortunately it seems that stopping the parent from exiting is impossible. And in terms of where the actual daemon is started - it's right there. I'm using this https://pypi.python.org/pypi/python-daemon/ – Sheena Feb 26 '14 at 14:45