Override getttext.find to cache result

This monkey patches gettext to cache the results of gettext.find. This
allows to drastically reduces system calls made over time for checking
the existence of mo files, which don't move.

Change-Id: I1464f131b90123aab67ef45ae2a2685a3ba111ef
This commit is contained in:
Thomas Herve 2018-10-22 14:27:35 +02:00
parent 89a48dfadc
commit a5fde9a90a
2 changed files with 36 additions and 0 deletions

View File

@ -99,3 +99,29 @@ def get_available_languages(domain):
_AVAILABLE_LANGUAGES[domain] = result
return copy.copy(result)
_original_find = gettext.find
_FIND_CACHE = {}
def cached_find(domain, localedir=None, languages=None, all=0):
"""A version of gettext.find using a cache.
gettext.find looks for mo files on the disk using os.path.exists. Those
don't tend to change over time, but the system calls pile up with a
long-running service. This caches the result so that we return the same mo
files, and only call find once per domain.
"""
key = (domain,
localedir,
tuple(languages) if languages is not None else None,
all)
if key in _FIND_CACHE:
return _FIND_CACHE[key]
result = _original_find(domain, localedir, languages, all)
_FIND_CACHE[key] = result
return result
gettext.find = cached_find

View File

@ -129,3 +129,13 @@ class GettextTest(test_base.BaseTestCase):
unknown_domain_languages = _gettextutils.get_available_languages('huh')
self.assertEqual(1, len(unknown_domain_languages))
self.assertIn('en_US', unknown_domain_languages)
def test_cached_find(self):
domain = 'my-unique-domain'
key = (domain, None, None, 0)
self.assertNotIn(key, _gettextutils._FIND_CACHE)
gettext.find(domain)
self.assertIn(key, _gettextutils._FIND_CACHE)
_gettextutils._FIND_CACHE[key] = "spoof result"
self.assertEqual("spoof result", gettext.find(domain))
_gettextutils._FIND_CACHE.pop(key)