Skip to content

Commit

Permalink
Fixed #30361 -- Increased the default timeout of watchman client to 5…
Browse files Browse the repository at this point in the history
… seconds and made it customizable.

Made the default timeout of watchman client customizable via
DJANGO_WATCHMAN_TIMEOUT environment variable.
  • Loading branch information
Jacob Green authored and felixxm committed Apr 26, 2019
1 parent efeceba commit ed3c590
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 2 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,7 @@ answer newbie questions, and generally made Django that much better:
Jaap Roes <[email protected]>
Jack Moffitt <https://metajack.im/>
Jacob Burch <[email protected]>
Jacob Green
Jacob Kaplan-Moss <[email protected]>
Jakub Paczkowski <[email protected]>
Jakub Wilk <[email protected]>
Expand Down
5 changes: 3 additions & 2 deletions django/utils/autoreload.py
Original file line number Diff line number Diff line change
Expand Up @@ -366,11 +366,12 @@ class WatchmanReloader(BaseReloader):
def __init__(self):
self.roots = defaultdict(set)
self.processed_request = threading.Event()
self.client_timeout = int(os.environ.get('DJANGO_WATCHMAN_TIMEOUT', 5))
super().__init__()

@cached_property
def client(self):
return pywatchman.client()
return pywatchman.client(timeout=self.client_timeout)

def _watch_root(self, root):
# In practice this shouldn't occur, however, it's possible that a
Expand Down Expand Up @@ -528,7 +529,7 @@ def check_server_status(self, inner_ex=None):
def check_availability(cls):
if not pywatchman:
raise WatchmanUnavailable('pywatchman not installed.')
client = pywatchman.client(timeout=0.01)
client = pywatchman.client(timeout=0.1)
try:
result = client.capabilityCheck()
except Exception:
Expand Down
5 changes: 5 additions & 0 deletions docs/ref/django-admin.txt
Original file line number Diff line number Diff line change
Expand Up @@ -897,6 +897,11 @@ more robust change detection, and a reduction in power usage.
for optimal performance. See the `watchman documentation`_ for information
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/
.. _pywatchman: https://pypi.org/project/pywatchman/
.. _watchman documentation: https://facebook.github.io/watchman/docs/config.html#ignore_dirs
Expand Down
4 changes: 4 additions & 0 deletions docs/releases/2.2.1.txt
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,7 @@ Bugfixes
:class:`~django.contrib.sessions.middleware.SessionMiddleware` subclasses,
rather than requiring :mod:`django.contrib.sessions` to be in
: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`).
9 changes: 9 additions & 0 deletions tests/utils_tests/test_autoreload.py
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,11 @@ def skip_unless_watchman_available():
class WatchmanReloaderTests(ReloaderTests, IntegrationTests):
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):
with mock.patch.object(self.reloader, '_subscribe') as mocked_subscribe:
self.reloader._watch_glob(self.tempdir / 'does_not_exist' / 'more', ['*'])
Expand Down Expand Up @@ -638,6 +643,10 @@ class TestException(Exception):
self.reloader.update_watches()
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")
class StatReloaderTests(ReloaderTests, IntegrationTests):
Expand Down

0 comments on commit ed3c590

Please sign in to comment.