public
Created

get or create multi for dogpile.cache based on @zzzeek's 33.patch

  • Download Gist
get_or_create_multi.py
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
def get_or_create_multi(self, keys, creator, expiration_time=None,
should_cache_fn=None):
 
def get_value():
value = values.get(key, NO_VALUE)
if value is NO_VALUE or \
value.metadata['v'] != value_version or \
(self._invalidated and
value.metadata["ct"] < self._invalidated):
invalidated.append(key)
return invalid, expiration_time
else:
return value.payload, value.metadata["ct"]
 
def gen_value():
raise NotImplementedError()
 
def async_creator(mutex):
mutexes.append(mutex)
 
# sort keys to prevent deadlock
keys = sorted(keys)
 
if self.key_mangler:
keys = [self.key_mangler(k) for k in keys]
 
if expiration_time is None:
expiration_time = self.expiration_time
 
invalidated = []
mutexes = []
keys_to_get = []
invalid = object()
 
values = self.backend.get_multi(keys)
 
for key in keys:
with Lock(self._mutex(key),
gen_value,
get_value,
expiration_time,
async_creator) as value:
if value is invalid:
keys_to_get.append(key)
try:
# create new keys if needed
if keys_to_get:
created_values = creator(keys_to_get)
new_values = dict(
(k, self._value(v))
for k, v in created_values.items()
)
values.update(new_values)
 
self.backend.set_multi(dict(
(k, new_values[k])
for k, v in created_values.items()
if not should_cache_fn or should_cache_fn(v)
))
return dict((k, v.payload) for k, v in values.items())
finally:
for mutex in mutexes:
mutex.release()

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.