daemonocle
daemonocle copied to clipboard
PID file deleted but process not terminated
What happens to me on every second or third restart of my process is that Daemonocle claims the process was not running, deletes the PID file, and starts it again. This fails because, in fact, the process was still running, and it binds to a port so the second instance crashes quickly when it can’t bind to the port.
My fix has been to determine the PID (with ps
), echo
it back into the PID file, and try again. On the second try it usually or always succeeds.
telofy@nyx ~/c/lexicockpit (master)> ../lexicockpit/bin/server restart
WARNING: lexicockpit.wsgi is not running
Starting lexicockpit.wsgi ... OK
telofy@nyx ~/c/lexicockpit (master)> ps aux | grep lexico
telofy 8266 0.0 0.2 136940 32948 ? S 17:26 0:00 /usr/bin/python3.4 ../lexicockpit/bin/server restart
telofy 8772 0.0 0.0 12732 2300 pts/0 S+ 17:27 0:00 grep --color=auto lexico
telofy 16547 0.0 0.2 136940 33212 ? S 16:29 0:00 /usr/bin/python3.4 ../lexicockpit/bin/server restart
telofy@nyx ~/c/lexicockpit (master)> echo 8266 > daemonocle.pid
telofy@nyx ~/c/lexicockpit (master)> ../lexicockpit/bin/server restart
Stopping lexicockpit.wsgi ... OK
Starting lexicockpit.wsgi ... OK
The process is a Python 3.4 Django application run by Gunicorn on a Debian-based system (Linux nyx 3.16.0-4-amd64 #1 SMP Debian 3.16.36-1+deb8u1 (2016-09-03) x86_64 GNU/Linux
).
The Daemonocle invocation looks like this:
daemon = daemonocle.Daemon(
worker=StandaloneApplication(application, settings.GUNICORN_SETTINGS).run,
workdir='.',
prog=__name__,
pidfile='daemonocle.pid')
daemon.do_action(sys.argv[1])
Thank you!
Sorry for the delay. Is gunicorn trying to daemonize itself? If so, that would mess things up. It needs to run in the foreground and let daemonocle do all the daemonization.
Nope, the daemon
parameter is false
by default. And I tried it out too – no daemonization when I start it on the command line.
GUNICORN_SETTINGS = {
'bind': '0.0.0.0:9001',
'workers': 1,
'reload': False,
'daemon': False,
'accesslog': os.path.join(BASE_DIR, 'logs/access.log'),
'errorlog': os.path.join(BASE_DIR, 'logs/error.log'),
}