In my environment, under version 2.0.2, I see exceptions like this regularly when calling Client.bucket("somebucketname"):
File "/usr/lib/python2.7/dist-packages/riak/client/__init__.py", line 243, in bucket
return self._buckets[name]
File "/usr/lib/python2.7/weakref.py", line 56, in __getitem__
o = self.data[key]()
KeyError: 'somebucketname'
https://github.com/basho/riak-python-client/blob/master/riak/client/__init__.py#L229-230
I believe this is a race condition between these two lines of client/__init__.py:
if (bucket_type, name) in self._buckets:
return self._buckets[(bucket_type, name)]
else:
# ... create a bucket object and cache it in self._buckets ...
What I believe is happening is that in between the bucket in self._buckets condition being tested and the bucket being pulled out of the self._buckets WeakValueDictionary, another thread has decremented the last refcount on that Bucket object and the garbage collector has reaped it.
I wonder if this could be done in another way, like this:
try:
return self._buckets[(bucket_type, name)]
except KeyError:
# The bucket doesn't exist in the cache, create it and add it.
Would this avoid the race?
Note that while I'm using version 2.0.2 and current is 2.1.0, the flow of this code is the same. The condition is tested, then the bucket is pulled out of the WeakValueDict.
In my environment, under version 2.0.2, I see exceptions like this regularly when calling Client.bucket("somebucketname"):
https://github.com/basho/riak-python-client/blob/master/riak/client/__init__.py#L229-230
I believe this is a race condition between these two lines of
client/__init__.py:What I believe is happening is that in between the
bucket in self._bucketscondition being tested and the bucket being pulled out of theself._bucketsWeakValueDictionary, another thread has decremented the last refcount on that Bucket object and the garbage collector has reaped it.I wonder if this could be done in another way, like this:
Would this avoid the race?
Note that while I'm using version 2.0.2 and current is 2.1.0, the flow of this code is the same. The condition is tested, then the bucket is pulled out of the WeakValueDict.