How do you use python-daemon the way that it's documentation dictates?

自作多情 提交于 2020-01-12 18:44:41

问题


I'm trying to make a daemon in python and I've come across the python-daemon package. The interesting thing about it is that the most common way I've seen it used isn't even what the documentation, which is very sparse, tells you to do

import os
import grp
import signal
import daemon
import lockfile

from spam import (
    initial_program_setup,
    do_main_program,
    program_cleanup,
    reload_program_config,
    )

context = daemon.DaemonContext(
    working_directory='/var/lib/foo',
    umask=0o002,
    pidfile=lockfile.FileLock('/var/run/spam.pid'),
    )

context.signal_map = {
    signal.SIGTERM: program_cleanup,
    signal.SIGHUP: 'terminate',
    signal.SIGUSR1: reload_program_config,
    }

mail_gid = grp.getgrnam('mail').gr_gid
context.gid = mail_gid

important_file = open('spam.data', 'w')
interesting_file = open('eggs.data', 'w')
context.files_preserve = [important_file, interesting_file]

initial_program_setup()

with context:
    do_main_program()

Instead, people use it like this:

#!/usr/bin/python
import time
from daemon import runner

class App():
    def __init__(self):
        self.stdin_path = '/dev/null'
        self.stdout_path = '/dev/tty'
        self.stderr_path = '/dev/tty'
        self.pidfile_path =  '/tmp/foo.pid'
        self.pidfile_timeout = 5
    def run(self):
        while True:
            print("Howdy!  Gig'em!  Whoop!")
            time.sleep(10)

app = App()
daemon_runner = runner.DaemonRunner(app)
daemon_runner.do_action()

Examples here and in this thread How do you create a daemon in Python?

So can anyone tell me how the package is supposed to be used as intended? There are 0 examples to be found that use it the way the documentation specifies.


回答1:


First, the reason you can't find good documentation is that, to the best of my knowledge, nobody ever wrote it. When Ben Finney proposed the PEP, there was plenty of interest, but then when he asked for someone else to take over the project and champion it, nobody did, so… beyond the PEP, and the sparse documentation in the docs directory of the project, there's really nothing but the source to explain things.

A DaemonContext is the way you're meant to create a daemon. Its API was bikeshedded extensively, and was the only part that was proposed to be part of the public interface in the stdlib. People from the Debian, Ubuntu, and RedHat/Fedora projects were involved in the initial discussion, and changes have been incorporated based on their experiences moving their distros to systemd.

A DaemonRunner wraps up a DaemonContext-based daemon and a control tool (ala apachectl). This implements a “service”, which is only one way of running a daemon out of many other different ways.

Often, you don't want this—if you want to build a "service", you usually want to only implement the daemon using a daemon.DaemonContext, and let systemd or launchd or their older predecessors manage the service by invoking that daemon. So, the PEP, to keep things simple, explicitly said that a service is outside the scope of what the daemon module should attempt.

But there is code for services in the python-daemon distribution. It isn't fully documented, because it is only an example of one way to use a daemon.

It does appear to work, and it's definitely been maintained and updated over the years. So, if you want an apachectl-type tool, I think it makes sense to use a DaemonRunner; just make sure you read the docstrings and write some tests to make sure it's doing what you wanted.




回答2:


As abarnert says, the python-daemon documentation is meant to show how to write a daemon process: a program that detaches itself from the controlling terminal and has no parent process and runs in the background.

The python-daemon code doesn't dictate how to use that daemon in a service. To implement the service, you need something to run that daemon: systemd, init, upstart, launchd all can do the job.

As an (undocumented) example, the python-daemon code base includes a simple example runner. It is not part of writing a daemon, and better tools exist.

Write the daemon using the daemon.daemon API as documented, and run it using a runner that comes with your operating system.



来源:https://stackoverflow.com/questions/30408589/how-do-you-use-python-daemon-the-way-that-its-documentation-dictates

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!