summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Herve <therve@redhat.com>2018-10-22 14:27:35 +0200
committerThomas Herve <therve@redhat.com>2018-11-21 14:45:52 +0100
commita5fde9a90a8216f70129c20d348f1f615b8842f3 (patch)
treea06093eb340e09780d36148dfb2b58e263176153
parent89a48dfadc964f781d86ea1c43bfd4319c316466 (diff)
downloadoslo-i18n-a5fde9a90a8216f70129c20d348f1f615b8842f3.tar.gz
Override getttext.find to cache result3.23.0
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
-rw-r--r--oslo_i18n/_gettextutils.py26
-rw-r--r--oslo_i18n/tests/test_gettextutils.py10
2 files changed, 36 insertions, 0 deletions
diff --git a/oslo_i18n/_gettextutils.py b/oslo_i18n/_gettextutils.py
index 9153b36..00028a6 100644
--- a/oslo_i18n/_gettextutils.py
+++ b/oslo_i18n/_gettextutils.py
@@ -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
diff --git a/oslo_i18n/tests/test_gettextutils.py b/oslo_i18n/tests/test_gettextutils.py
index 6a30a95..2eca069 100644
--- a/oslo_i18n/tests/test_gettextutils.py
+++ b/oslo_i18n/tests/test_gettextutils.py
@@ -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)