mirror of
https://github.com/frappe/gunicorn.git
synced 2026-01-14 11:09:11 +08:00
add systemd sd_notify support (#1897)
* add systemd sd_notify support roughly based on sd_notify() from systemd and https://github.com/bb4242/sdnotify only implements `READY=1` and `STATUS=Gunicorn arbiter booted` of the protocol in the arbiter. in the future, reloads can be notified, and possibly also other statuses. see https://www.freedesktop.org/software/systemd/man/sd_notify.html for more info sd_notify() is a noop when not run in a systemd service (i.e NOTIFY_SOCKET environment variable is not set)
This commit is contained in:
parent
ad1afe7b79
commit
9184ae8898
@ -227,7 +227,7 @@ unix socket:
|
|||||||
After=network.target
|
After=network.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
PIDFile=/run/gunicorn/pid
|
Type=notify
|
||||||
User=someuser
|
User=someuser
|
||||||
Group=someuser
|
Group=someuser
|
||||||
RuntimeDirectory=gunicorn
|
RuntimeDirectory=gunicorn
|
||||||
|
|||||||
@ -158,6 +158,7 @@ class Arbiter(object):
|
|||||||
self.log.debug("Arbiter booted")
|
self.log.debug("Arbiter booted")
|
||||||
self.log.info("Listening at: %s (%s)", listeners_str, self.pid)
|
self.log.info("Listening at: %s (%s)", listeners_str, self.pid)
|
||||||
self.log.info("Using worker: %s", self.cfg.worker_class_str)
|
self.log.info("Using worker: %s", self.cfg.worker_class_str)
|
||||||
|
systemd.sd_notify("READY=1\nSTATUS=Gunicorn arbiter booted", self.log)
|
||||||
|
|
||||||
# check worker class requirements
|
# check worker class requirements
|
||||||
if hasattr(self.worker_class, "check_config"):
|
if hasattr(self.worker_class, "check_config"):
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
# See the NOTICE for more information.
|
# See the NOTICE for more information.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import socket
|
||||||
|
|
||||||
SD_LISTEN_FDS_START = 3
|
SD_LISTEN_FDS_START = 3
|
||||||
|
|
||||||
@ -43,3 +44,34 @@ def listen_fds(unset_environment=True):
|
|||||||
os.environ.pop('LISTEN_FDS', None)
|
os.environ.pop('LISTEN_FDS', None)
|
||||||
|
|
||||||
return fds
|
return fds
|
||||||
|
|
||||||
|
|
||||||
|
def sd_notify(state, logger, unset_environment=False):
|
||||||
|
"""Send a notification to systemd. state is a string; see
|
||||||
|
the man page of sd_notify (http://www.freedesktop.org/software/systemd/man/sd_notify.html)
|
||||||
|
for a description of the allowable values.
|
||||||
|
|
||||||
|
If the unset_environment parameter is True, sd_notify() will unset
|
||||||
|
the $NOTIFY_SOCKET environment variable before returning (regardless of
|
||||||
|
whether the function call itself succeeded or not). Further calls to
|
||||||
|
sd_notify() will then fail, but the variable is no longer inherited by
|
||||||
|
child processes.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
addr = os.environ.get('NOTIFY_SOCKET')
|
||||||
|
if addr is None:
|
||||||
|
# not run in a service, just a noop
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM | socket.SOCK_CLOEXEC)
|
||||||
|
if addr[0] == '@':
|
||||||
|
addr = '\0' + addr[1:]
|
||||||
|
sock.connect(addr)
|
||||||
|
sock.sendall(state.encode('utf-8'))
|
||||||
|
except:
|
||||||
|
logger.debug("Exception while invoking sd_notify()", exc_info=True)
|
||||||
|
finally:
|
||||||
|
if unset_environment:
|
||||||
|
os.environ.pop('NOTIFY_SOCKET')
|
||||||
|
sock.close()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user