import os
import sys
[docs]
class ReloadMethod:
identifier = None
title = None
[docs]
def execute(self):
raise NotImplementedError("Error! Not implemented: `ReloadMethod` -> `execute()`.")
[docs]
def is_viable(self):
return False
[docs]
class UwsgiReloadMethod(ReloadMethod):
# http://uwsgi-docs.readthedocs.org/en/latest/PythonModule.html#uwsgi.reload
identifier = "uwsgi"
title = "Reload uWSGI (uwsgi.reload())"
[docs]
def is_viable(self):
try:
import uwsgi
return callable(uwsgi.reload)
except ImportError: # Not uWSGI or not a supported version
return False
[docs]
def execute(self):
import uwsgi
uwsgi.reload()
[docs]
class DevServerReloadMethod(ReloadMethod):
identifier = "devserver"
title = "Reload Django Dev Server"
[docs]
def is_viable(self):
return (
("runserver" in sys.argv or "devserver" in sys.argv)
and ("noreload" not in sys.argv)
and os.environ.get("RUN_MAIN")
)
[docs]
def execute(self):
# `sys.exit(3)` is what `reloader_thread` would use, but
# the `SystemExit` exception will be caught by Django, so
# we'll have to resort to ugliness.
os._exit(3)
[docs]
class ModWSGIReloadMethod(ReloadMethod):
# https://code.google.com/p/modwsgi/wiki/ReloadingSourceCode#Restarting_Daemon_Processes
identifier = "mod_wsgi"
title = "Reload Daemon Mode mod_wsgi"
[docs]
def is_viable(self):
return bool(os.environ.get("mod_wsgi.process_group"))
[docs]
def execute(self):
import os
import signal
os.kill(os.getpid(), signal.SIGINT)
[docs]
class GunicornReloadMethod(ReloadMethod):
# http://docs.gunicorn.org/en/latest/faq.html#how-do-i-reload-my-application-in-gunicorn
identifier = "gunicorn"
title = "Reload Gunicorn Master"
[docs]
def is_parent_an_unicorn(self):
try:
return "gunicorn" in open(f"/proc/{os.getppid()}/cmdline").read()
except (OSError, AttributeError):
return False
[docs]
def is_viable(self):
# See if we have Gunicorn available
try:
import gunicorn
assert gunicorn # Yup, unicorns alright!
except ImportError:
return False
# See if our parent process (assumed Gunicorn master) smells like an unicorn
return self.is_parent_an_unicorn()
[docs]
def execute(self):
import os
import signal
if self.is_parent_an_unicorn():
os.kill(os.getppid(), signal.SIGHUP)
raise ValueError("Error! My parent doesn't look like an unicorn.")
[docs]
def get_reload_method_classes():
yield UwsgiReloadMethod
yield DevServerReloadMethod
yield ModWSGIReloadMethod
yield GunicornReloadMethod