dgilland / cacheout

A caching library for Python
https://cacheout.readthedocs.io
MIT License
425 stars 44 forks source link

OrderedDict Mutated during Iteration #17

Closed calebebrim closed 3 years ago

calebebrim commented 3 years ago

Code:

This is the code I'm using python=3.6

from cacheout import Cache
import time
import os
import re

TIMED_WINDOW = os.getenv('TIMED_WINDOW', 3)
MAX_EVENTS = 256

c = Cache(maxsize=MAX_EVENTS, ttl=TIMED_WINDOW, timer=time.time)
c.set('v1', 1)
c.set('v2', 2)
c.set('v3', 3)
time.sleep(1)
print(c.get_many(re.compile(r"v.*")))
print(c.get_many(re.compile(r"a.*")))
c.set('a1', 1)
c.set('a2', 2)
c.set('a3', 3)
time.sleep(1)
print(c.get_many(re.compile(r"v.*")))
print(c.get_many(re.compile(r"a.*")))
time.sleep(1)
print(c.get_many(re.compile(r"v.*")))
print(c.get_many(re.compile(r"a.*")))
time.sleep(1)
print(c.get_many(re.compile(r"v.*")))
print(c.get_many(re.compile(r"a.*")))
time.sleep(1)
print(c.get_many(re.compile(r"v.*")))
print(c.get_many(re.compile(r"a.*")))
time.sleep(1)
print(c.get_many(re.compile(r"v.*")))
print(c.get_many(re.compile(r"a.*")))

Error:

Traceback (most recent call last):
  File "windowed.py", line 24, in <module>
    print(c.get_many(re.compile(r"v.*")))
  File "C:\tools\Anaconda3\envs\py36\lib\site-packages\cacheout\cache.py", line 248, in get_many
    return {key: self.get(key, default=default) for key in self._filter(iteratee)}
  File "C:\tools\Anaconda3\envs\py36\lib\site-packages\cacheout\cache.py", line 248, in <dictcomp>
    return {key: self.get(key, default=default) for key in self._filter(iteratee)}
  File "C:\tools\Anaconda3\envs\py36\lib\site-packages\cacheout\cache.py", line 500, in _filter
    yield from filter(filter_by, target)
RuntimeError: OrderedDict mutated during iteration

I think that when it try to get many it is removing the cache by ttl rule.

dgilland commented 3 years ago

Thanks for reporting the bug!

This is fixed in 0.13.0: https://pypi.org/project/cacheout/0.13.0/