mirror of
https://github.com/frappe/gunicorn.git
synced 2026-01-14 11:09:11 +08:00
Modify 'reload' config to be more consistent with existing API
--reload = Runs the reloader with inotify if available and falls back on
FS polling.
--reload=inotify = Forces the reloader to run with inotify
--reload=poll = Forces the reloader to use FS polling
This commit is contained in:
parent
64b26ef766
commit
92d48256e4
@ -489,6 +489,19 @@ def validate_hostport(val):
|
|||||||
else:
|
else:
|
||||||
raise TypeError("Value must consist of: hostname:port")
|
raise TypeError("Value must consist of: hostname:port")
|
||||||
|
|
||||||
|
|
||||||
|
def validate_reloader(val):
|
||||||
|
if val is None:
|
||||||
|
val = 'default'
|
||||||
|
|
||||||
|
choices = ['poll', 'inotify', 'default']
|
||||||
|
|
||||||
|
if val not in choices:
|
||||||
|
raise ConfigError(
|
||||||
|
'Invalid reloader type. Must be one of: %s' % choices
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_default_config_file():
|
def get_default_config_file():
|
||||||
config_path = os.path.join(os.path.abspath(os.getcwd()),
|
config_path = os.path.join(os.path.abspath(os.getcwd()),
|
||||||
'gunicorn.conf.py')
|
'gunicorn.conf.py')
|
||||||
@ -806,9 +819,11 @@ class Reload(Setting):
|
|||||||
name = "reload"
|
name = "reload"
|
||||||
section = 'Debugging'
|
section = 'Debugging'
|
||||||
cli = ['--reload']
|
cli = ['--reload']
|
||||||
validator = validate_bool
|
validator = validate_reloader
|
||||||
action = 'store_true'
|
nargs = '?'
|
||||||
default = False
|
const = 'default'
|
||||||
|
default = None
|
||||||
|
|
||||||
desc = '''\
|
desc = '''\
|
||||||
Restart workers when code changes.
|
Restart workers when code changes.
|
||||||
|
|
||||||
@ -818,24 +833,14 @@ class Reload(Setting):
|
|||||||
The reloader is incompatible with application preloading. When using a
|
The reloader is incompatible with application preloading. When using a
|
||||||
paste configuration be sure that the server block does not import any
|
paste configuration be sure that the server block does not import any
|
||||||
application code or the reload will not work as designed.
|
application code or the reload will not work as designed.
|
||||||
|
|
||||||
|
When using this option, you can optionally specify whether you would
|
||||||
|
like to use file system polling or the kernel's inotify API to watch
|
||||||
|
for changes. Generally, inotify should be preferred if available
|
||||||
|
because it consumes less system resources. If no preference is given,
|
||||||
|
inotify will attempted with a fallback to FS polling.'
|
||||||
'''
|
'''
|
||||||
|
|
||||||
class ReloadInotify(Setting):
|
|
||||||
name = 'inotify'
|
|
||||||
section = 'Debugging'
|
|
||||||
cli = ['--use-inotify']
|
|
||||||
validator = validate_bool
|
|
||||||
action = "store_true"
|
|
||||||
default = False
|
|
||||||
|
|
||||||
desc = '''\
|
|
||||||
When using the 'reload' option, use the kernel's inotify APIs to watch
|
|
||||||
files instead of polling the filesystem. On many systems this could result
|
|
||||||
in a performance improvement when using 'reload'.
|
|
||||||
|
|
||||||
This setting must be used in conjunction with 'reload' and requires the
|
|
||||||
'inotify' package be installed from PyPI.
|
|
||||||
'''
|
|
||||||
|
|
||||||
class Spew(Setting):
|
class Spew(Setting):
|
||||||
name = "spew"
|
name = "spew"
|
||||||
|
|||||||
@ -60,9 +60,11 @@ try:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
has_inotify = False
|
has_inotify = False
|
||||||
|
|
||||||
|
|
||||||
class InotifyReloader():
|
class InotifyReloader():
|
||||||
def __init__(self, callback=None):
|
def __init__(self, callback=None):
|
||||||
raise ImportError('You must have the inotify module installed to use the INotify reloader')
|
raise ImportError('You must have the inotify module installed to use '
|
||||||
|
'the inotify reloader')
|
||||||
|
|
||||||
if has_inotify:
|
if has_inotify:
|
||||||
|
|
||||||
@ -107,9 +109,9 @@ if has_inotify:
|
|||||||
if event is None:
|
if event is None:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
types = event[1]
|
|
||||||
filename = event[3]
|
filename = event[3]
|
||||||
|
|
||||||
self._callback(filename)
|
self._callback(filename)
|
||||||
|
|
||||||
|
|
||||||
|
preferred_reloader = InotifyReloader if has_inotify else Reloader
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import traceback
|
|||||||
|
|
||||||
from gunicorn import util
|
from gunicorn import util
|
||||||
from gunicorn.workers.workertmp import WorkerTmp
|
from gunicorn.workers.workertmp import WorkerTmp
|
||||||
from gunicorn.reloader import Reloader, InotifyReloader, has_inotify
|
from gunicorn.reloader import preferred_reloader, Reloader, InotifyReloader
|
||||||
from gunicorn.http.errors import (
|
from gunicorn.http.errors import (
|
||||||
InvalidHeader, InvalidHeaderName, InvalidRequestLine, InvalidRequestMethod,
|
InvalidHeader, InvalidHeaderName, InvalidRequestLine, InvalidRequestMethod,
|
||||||
InvalidHTTPVersion, LimitRequestLine, LimitRequestHeaders,
|
InvalidHTTPVersion, LimitRequestLine, LimitRequestHeaders,
|
||||||
@ -123,7 +123,13 @@ class Worker(object):
|
|||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
reloader_cls = Reloader if not self.cfg.inotify else InotifyReloader
|
if self.cfg.reload == 'poll':
|
||||||
|
reloader_cls = Reloader
|
||||||
|
elif self.cfg.reload == 'inotify':
|
||||||
|
reloader_cls = InotifyReloader
|
||||||
|
else:
|
||||||
|
reloader_cls = preferred_reloader
|
||||||
|
|
||||||
self.reloader = reloader_cls(callback=changed)
|
self.reloader = reloader_cls(callback=changed)
|
||||||
self.reloader.start()
|
self.reloader.start()
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user