Skip to content

Commit b530ae5

Browse files
committed
Merge branch 'hannes-fix-cache-race' into develop
PR #197. * hannes-fix-cache-race: Add bug fix to changelog Update test to ensure it fails Fix race condition in cache eviction
2 parents 1c0f538 + 7969813 commit b530ae5

File tree

3 files changed

+30
-2
lines changed

3 files changed

+30
-2
lines changed

CHANGELOG.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ Next Release (TBD)
33

44
* Python 2.6 and 3.3 have reached end-of-life and have been deprecated.
55
(`issue 175 <https://github.com/jmespath/jmespath.py/issues/175>`__)
6+
* Fix race condition when clearing cached parsed expressions.
7+
(`issue 197 <https://github.com/jmespath/jmespath.py/pull/197>`__)
68

79

810
0.9.5

jmespath/parser.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,7 @@ def _raise_parse_error_maybe_eof(self, expected_type, token):
490490

491491
def _free_cache_entries(self):
492492
for key in random.sample(self._CACHE.keys(), int(self._MAX_SIZE / 2)):
493-
del self._CACHE[key]
493+
self._CACHE.pop(key, None)
494494

495495
@classmethod
496496
def purge(cls):

tests/test_parser.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#!/usr/bin/env python
2-
32
import re
3+
import random
4+
import string
5+
import threading
46
from tests import unittest, OrderedDict
57

68
from jmespath import parser
@@ -322,6 +324,30 @@ def test_cache_purge(self):
322324
self.assertEqual(first.parsed,
323325
cached.parsed)
324326

327+
def test_thread_safety_of_cache(self):
328+
errors = []
329+
expressions = [
330+
''.join(random.choice(string.ascii_letters) for _ in range(3))
331+
for _ in range(2000)
332+
]
333+
def worker():
334+
p = parser.Parser()
335+
for expression in expressions:
336+
try:
337+
p.parse(expression)
338+
except Exception as e:
339+
errors.append(e)
340+
341+
threads = []
342+
for i in range(10):
343+
threads.append(threading.Thread(target=worker))
344+
for thread in threads:
345+
thread.start()
346+
for thread in threads:
347+
thread.join()
348+
349+
self.assertEqual(errors, [])
350+
325351

326352
class TestParserAddsExpressionAttribute(unittest.TestCase):
327353
def test_expression_available_from_parser(self):

0 commit comments

Comments
 (0)