Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KeyError on value assignment #90

Closed
jjaquinta opened this issue Oct 24, 2017 · 5 comments
Closed

KeyError on value assignment #90

jjaquinta opened this issue Oct 24, 2017 · 5 comments

Comments

@jjaquinta
Copy link

Sorry for the obfuscation, but IP and all that.
In the code below collectionCache is a TTLCache. I'm assigning a value into it and it is throwing a KeyError in your code. From the logic of your code, I can't see how this could ever happen. But we get it consistently. We're using python 2.7 and cachetools-1.1.6.

10/24/2017 10:31:12 AM  File "/xxx/xxx/xxx/xxx/xxx/xxx/xxx.py", line 143, in xxx
10/24/2017 10:31:12 AM    self.collectionCache["COLLECTION:"+str(collectionName)+"-ORG:"+str(params["ORGID"])] = cacheDict
10/24/2017 10:31:12 AM  File "/usr/local/lib/python2.7/site-packages/cachetools/ttl.py", line 89, in __setitem__
10/24/2017 10:31:12 AM    self.expire(time)
10/24/2017 10:31:12 AM  File "/usr/local/lib/python2.7/site-packages/cachetools/ttl.py", line 169, in expire
10/24/2017 10:31:12 AM    cache_delitem(self, curr.key)
10/24/2017 10:31:12 AM  File "/usr/local/lib/python2.7/site-packages/cachetools/cache.py", line 62, in __delitem__
10/24/2017 10:31:12 AM    del self.__data[key]
10/24/2017 10:31:12 AMKeyError: 'COLLECTION:@SUBNET_1201023-ORG:202'
@tkem
Copy link
Owner

tkem commented Oct 24, 2017

Is your code multi-threaded?

@jjaquinta
Copy link
Author

Yep. Very much so. However, the fault was repeatable. So this particular callstack isn't a race condition problem.
However, despite working on this since Friday, we were not able to reproduce the problem in any of our test environments. Or even in a test environment against production data. We restarted the production process and the problem went away. >_<
So, my guess is that some sort of multi-thread event caused a data corruption problem within the object. And, once the data corruption was there, further accesses caused the fault recorded above. Finding the causal reason... I don't know if we'll ever get there. But I figured the information would be useful.
But if your class isn't thread safe, well, that's something we should act on. We have been assuming it is.

@tkem
Copy link
Owner

tkem commented Oct 24, 2017

Contrary to popular believe, Cache instances are not thread-safe. Neither is, for example, OrderedDict or most of the classes in Python's standard library. Since this is a recurring theme - see also #80 and #82 - I guess this should be stated more prominently in the docs. The @cached and @cachedmethod decorators have an explicit lock argument which can be used to achieve thread-safety. Maybe that's something that could be useful.

@jjaquinta
Copy link
Author

Yep. Did not see that in the doc at all. We're still trying to trace which pip install in our pipeline loaded your code. :-) I'll queue up some tasks to thread-safe this. Thanks for the info.

@tkem
Copy link
Owner

tkem commented Oct 24, 2017

I didn't deem it necessary to make this more explicit in the docs because I consider it good practice to assume a class is not thread-safe unless explicitly stated otherwise. Most classes in the Python standard library are not thread-safe, and don't bother to say so. Even plain old dict is not thread-safe if you use custom classes as keys which implement __hash__ in Python code, for example. But since this seems to be such a popular misconception, I guess I'll add a note or something...
Closing this for now. Feel free to reopen if you still experience this issue after putting proper locks around your shared cache instances.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants