Skip to content

Commit

Permalink
Restore the API for async_creation_runner in all cases
Browse files Browse the repository at this point in the history
Fixed regression in 0.7.0 caused by 🎫`136` where the assumed
arguments for the :paramref:`.CacheRegion.async_creation_runner` expanded to
include the new :paramref:`.CacheRegion.get_or_create.creator_args`
parameter, as it was not tested that the async runner would be implicitly
called with these arguments when the :meth:`.CacheRegion.cache_on_arguments`
decorator was used.  The exact signature of ``async_creation_runner`` is
now restored to have the same arguments in all cases.

Fixes: #139
Change-Id: I91c95b183e01d1bbe1c42b3375fcfa65866cc97d
  • Loading branch information
zzzeek committed Dec 12, 2018
1 parent 01bc28d commit 0ef7615
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 5 deletions.
12 changes: 12 additions & 0 deletions docs/build/unreleased/139.rst
@@ -0,0 +1,12 @@
.. change::
:tags: bug, region
:tickets: 139

Fixed regression in 0.7.0 caused by :ticket:`136` where the assumed
arguments for the :paramref:`.CacheRegion.async_creation_runner` expanded to
include the new :paramref:`.CacheRegion.get_or_create.creator_args`
parameter, as it was not tested that the async runner would be implicitly
called with these arguments when the :meth:`.CacheRegion.cache_on_arguments`
decorator was used. The exact signature of ``async_creation_runner`` is
now restored to have the same arguments in all cases.

10 changes: 5 additions & 5 deletions dogpile/cache/region.py
Expand Up @@ -862,12 +862,12 @@ def gen_value():
if self.async_creation_runner:
def async_creator(mutex):
if creator_args:
return self.async_creation_runner(
self, orig_key, creator, mutex,
creator_args=creator_args)
@wraps(creator)
def go():
return creator(*creator_args[0], **creator_args[1])
else:
return self.async_creation_runner(
self, orig_key, creator, mutex)
go = creator
return self.async_creation_runner(self, orig_key, go, mutex)
else:
async_creator = None

Expand Down
74 changes: 74 additions & 0 deletions tests/cache/test_region.py
Expand Up @@ -11,6 +11,7 @@
import time
import datetime
import itertools
import mock
from collections import defaultdict
from ._fixtures import MockBackend

Expand Down Expand Up @@ -528,6 +529,79 @@ def _region(self, init_args={}, config_args={}, backend="mock"):
return reg


class AsyncCreatorTest(TestCase):
def _fixture(self):

def async_creation_runner(cache, somekey, creator, mutex):
try:
value = creator()
cache.set(somekey, value)
finally:
mutex.release()

return mock.Mock(side_effect=async_creation_runner)

def test_get_or_create(self):
acr = self._fixture()
reg = CacheRegion(async_creation_runner=acr)
reg.configure("mock", expiration_time=.2)

def some_value():
return "some value"

def some_new_value():
return "some new value"

eq_(reg.get_or_create("some key", some_value), "some value")
time.sleep(.5)
eq_(
reg.get_or_create("some key", some_new_value),
"some value")
eq_(
reg.get_or_create("some key", some_new_value),
"some new value")
eq_(
acr.mock_calls, [
mock.call(reg, "some key",
some_new_value, reg._mutex("some key"))
])

def test_fn_decorator(self):
acr = self._fixture()
reg = CacheRegion(async_creation_runner=acr)
reg.configure("mock", expiration_time=5)

canary = mock.Mock()

@reg.cache_on_arguments()
def go(x, y):
canary(x, y)
return x + y

eq_(go(1, 2), 3)
eq_(go(1, 2), 3)

eq_(canary.mock_calls, [mock.call(1, 2)])

eq_(go(3, 4), 7)

eq_(canary.mock_calls, [mock.call(1, 2), mock.call(3, 4)])

reg.invalidate(hard=False)

eq_(go(1, 2), 3)

eq_(canary.mock_calls, [
mock.call(1, 2), mock.call(3, 4), mock.call(1, 2)])

eq_(
acr.mock_calls, [
mock.call(reg, "tests.cache.test_region:go|1 2",
mock.ANY,
reg._mutex("tests.cache.test_region:go|1 2"))
])


class ProxyBackendTest(TestCase):

class GetCounterProxy(ProxyBackend):
Expand Down

0 comments on commit 0ef7615

Please sign in to comment.