Skip to content

Commit

Permalink
Escape job refresh
Browse files Browse the repository at this point in the history
  • Loading branch information
walison17 committed Oct 25, 2021
1 parent c7ddf0a commit eabb15d
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 1 deletion.
23 changes: 22 additions & 1 deletion cacheback/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,21 @@ def refresh(self, *args, **kwargs):
self.store(self.key(*args, **kwargs), self.expiry(*args, **kwargs), result)
return result

def should_refresh(self, *args, **kwargs):
"""
Verify if the cache should be refreshed
"""
expiry, data = self.cache.get(self.key(*args, **kwargs), (None, None))

if data is None:
return True

delta = expiry - time.time()
if delta > 0:
return False

return True

def async_refresh(self, *args, **kwargs):
"""
Trigger an asynchronous job to refresh the cache
Expand Down Expand Up @@ -479,10 +494,16 @@ def perform_async_refresh(cls, klass_str, obj_args, obj_kwargs, call_args, call_
logger.info(
"Using %s with constructor args %r and kwargs %r", klass_str, obj_args, obj_kwargs
)

job = klass(*obj_args, **obj_kwargs)
if not job.should_refresh(*call_args, **call_kwargs):
logger.info('Refresh escaped, cache is already fresh.')
return

logger.info("Calling refresh with args %r and kwargs %r", call_args, call_kwargs)
start = time.time()
try:
klass(*obj_args, **obj_kwargs).refresh(*call_args, **call_kwargs)
job.refresh(*call_args, **call_kwargs)
except Exception as e:
logger.exception("Error running job: '%s'", e)
else:
Expand Down
13 changes: 13 additions & 0 deletions tests/test_base_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,3 +291,16 @@ def test_job_refresh_perform_error(self, logger_mock):
def test_job_refresh(self):
Job.perform_async_refresh('tests.test_base_job.EmptyDummyJob', (), {}, ('foo',), {})
assert EmptyDummyJob().get('foo') is not None

@pytest.mark.redis_required
@mock.patch('tests.test_base_job.EmptyDummyJob.fetch', return_value='foo')
def test_escape_job_refresh(self, fetch_mock, rq_burst):
job = EmptyDummyJob()
job.task_options = {'is_async': False}

job.async_refresh('foo')
job.async_refresh('foo')

rq_burst()

assert fetch_mock.call_count == 1

0 comments on commit eabb15d

Please sign in to comment.