mirror of https://github.com/django/django.git
Fixed #30361 -- Increased the default timeout of watchman client to 5 seconds and made it customizable.
Made the default timeout of watchman client customizable via DJANGO_WATCHMAN_TIMEOUT environment variable.
This commit is contained in:
parent
efeceba589
commit
ed3c59097a
1
AUTHORS
1
AUTHORS
|
@ -364,6 +364,7 @@ answer newbie questions, and generally made Django that much better:
|
||||||
Jaap Roes <jaap.roes@gmail.com>
|
Jaap Roes <jaap.roes@gmail.com>
|
||||||
Jack Moffitt <https://metajack.im/>
|
Jack Moffitt <https://metajack.im/>
|
||||||
Jacob Burch <jacobburch@gmail.com>
|
Jacob Burch <jacobburch@gmail.com>
|
||||||
|
Jacob Green
|
||||||
Jacob Kaplan-Moss <jacob@jacobian.org>
|
Jacob Kaplan-Moss <jacob@jacobian.org>
|
||||||
Jakub Paczkowski <jakub@paczkowski.eu>
|
Jakub Paczkowski <jakub@paczkowski.eu>
|
||||||
Jakub Wilk <jwilk@jwilk.net>
|
Jakub Wilk <jwilk@jwilk.net>
|
||||||
|
|
|
@ -366,11 +366,12 @@ class WatchmanReloader(BaseReloader):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.roots = defaultdict(set)
|
self.roots = defaultdict(set)
|
||||||
self.processed_request = threading.Event()
|
self.processed_request = threading.Event()
|
||||||
|
self.client_timeout = int(os.environ.get('DJANGO_WATCHMAN_TIMEOUT', 5))
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def client(self):
|
def client(self):
|
||||||
return pywatchman.client()
|
return pywatchman.client(timeout=self.client_timeout)
|
||||||
|
|
||||||
def _watch_root(self, root):
|
def _watch_root(self, root):
|
||||||
# In practice this shouldn't occur, however, it's possible that a
|
# In practice this shouldn't occur, however, it's possible that a
|
||||||
|
@ -528,7 +529,7 @@ class WatchmanReloader(BaseReloader):
|
||||||
def check_availability(cls):
|
def check_availability(cls):
|
||||||
if not pywatchman:
|
if not pywatchman:
|
||||||
raise WatchmanUnavailable('pywatchman not installed.')
|
raise WatchmanUnavailable('pywatchman not installed.')
|
||||||
client = pywatchman.client(timeout=0.01)
|
client = pywatchman.client(timeout=0.1)
|
||||||
try:
|
try:
|
||||||
result = client.capabilityCheck()
|
result = client.capabilityCheck()
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|
|
@ -897,6 +897,11 @@ more robust change detection, and a reduction in power usage.
|
||||||
for optimal performance. See the `watchman documentation`_ for information
|
for optimal performance. See the `watchman documentation`_ for information
|
||||||
on how to do this.
|
on how to do this.
|
||||||
|
|
||||||
|
.. admonition:: Watchman timeout
|
||||||
|
|
||||||
|
The default timeout of ``Watchman`` client is 5 seconds. You can change it
|
||||||
|
by setting the ``DJANGO_WATCHMAN_TIMEOUT`` environment variable.
|
||||||
|
|
||||||
.. _Watchman: https://facebook.github.io/watchman/
|
.. _Watchman: https://facebook.github.io/watchman/
|
||||||
.. _pywatchman: https://pypi.org/project/pywatchman/
|
.. _pywatchman: https://pypi.org/project/pywatchman/
|
||||||
.. _watchman documentation: https://facebook.github.io/watchman/docs/config.html#ignore_dirs
|
.. _watchman documentation: https://facebook.github.io/watchman/docs/config.html#ignore_dirs
|
||||||
|
|
|
@ -55,3 +55,7 @@ Bugfixes
|
||||||
:class:`~django.contrib.sessions.middleware.SessionMiddleware` subclasses,
|
:class:`~django.contrib.sessions.middleware.SessionMiddleware` subclasses,
|
||||||
rather than requiring :mod:`django.contrib.sessions` to be in
|
rather than requiring :mod:`django.contrib.sessions` to be in
|
||||||
:setting:`INSTALLED_APPS` (:ticket:`30312`).
|
:setting:`INSTALLED_APPS` (:ticket:`30312`).
|
||||||
|
|
||||||
|
* Increased the default timeout when using ``Watchman`` to 5 seconds to prevent
|
||||||
|
falling back to ``StatReloader`` on larger projects and made it customizable
|
||||||
|
via the ``DJANGO_WATCHMAN_TIMEOUT`` environment variable (:ticket:`30361`).
|
||||||
|
|
|
@ -558,6 +558,11 @@ def skip_unless_watchman_available():
|
||||||
class WatchmanReloaderTests(ReloaderTests, IntegrationTests):
|
class WatchmanReloaderTests(ReloaderTests, IntegrationTests):
|
||||||
RELOADER_CLS = autoreload.WatchmanReloader
|
RELOADER_CLS = autoreload.WatchmanReloader
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super().setUp()
|
||||||
|
# Shorten the timeout to speed up tests.
|
||||||
|
self.reloader.client_timeout = 0.1
|
||||||
|
|
||||||
def test_watch_glob_ignores_non_existing_directories_two_levels(self):
|
def test_watch_glob_ignores_non_existing_directories_two_levels(self):
|
||||||
with mock.patch.object(self.reloader, '_subscribe') as mocked_subscribe:
|
with mock.patch.object(self.reloader, '_subscribe') as mocked_subscribe:
|
||||||
self.reloader._watch_glob(self.tempdir / 'does_not_exist' / 'more', ['*'])
|
self.reloader._watch_glob(self.tempdir / 'does_not_exist' / 'more', ['*'])
|
||||||
|
@ -638,6 +643,10 @@ class WatchmanReloaderTests(ReloaderTests, IntegrationTests):
|
||||||
self.reloader.update_watches()
|
self.reloader.update_watches()
|
||||||
self.assertIsInstance(mocked_server_status.call_args[0][0], TestException)
|
self.assertIsInstance(mocked_server_status.call_args[0][0], TestException)
|
||||||
|
|
||||||
|
@mock.patch.dict(os.environ, {'DJANGO_WATCHMAN_TIMEOUT': '10'})
|
||||||
|
def test_setting_timeout_from_environment_variable(self):
|
||||||
|
self.assertEqual(self.RELOADER_CLS.client_timeout, 10)
|
||||||
|
|
||||||
|
|
||||||
@skipIf(on_macos_with_hfs(), "These tests do not work with HFS+ as a filesystem")
|
@skipIf(on_macos_with_hfs(), "These tests do not work with HFS+ as a filesystem")
|
||||||
class StatReloaderTests(ReloaderTests, IntegrationTests):
|
class StatReloaderTests(ReloaderTests, IntegrationTests):
|
||||||
|
|
Loading…
Reference in New Issue