caches: use .refresh() instead of .invalidate()

- .invalidate() does a delete of cached valued under a key, which means
in previous logic we delete, get_or_create, and compute.
- .refresh() is simply replacing exising key with newly computed values, this
creates less locks, and it's faster.
This commit is contained in:
Marcin Kuzminski 2018-08-03 14:34:33 +02:00
parent 543be29fea
commit c218e2a9ea
5 changed files with 38 additions and 38 deletions

View file

@ -161,14 +161,12 @@ class RepoFeedView(RepoAppView):
inv_context_manager = rc_cache.InvalidationContext(
uid=cache_namespace_uid, invalidation_namespace=invalidation_namespace)
with inv_context_manager as invalidation_context:
# check for stored invalidation signal, and maybe purge the cache
# before computing it again
args = (self.db_repo.repo_id, self.db_repo.repo_name, 'atom',)
# re-compute and store cache if we get invalidate signal
if invalidation_context.should_invalidate():
generate_atom_feed.invalidate(
self.db_repo.repo_id, self.db_repo.repo_name, 'atom')
mime_type, feed = generate_atom_feed(
self.db_repo.repo_id, self.db_repo.repo_name, 'atom')
mime_type, feed = generate_atom_feed.refresh(*args)
else:
mime_type, feed = generate_atom_feed(*args)
log.debug('Repo ATOM feed computed in %.3fs',
inv_context_manager.compute_time)
@ -226,14 +224,12 @@ class RepoFeedView(RepoAppView):
inv_context_manager = rc_cache.InvalidationContext(
uid=cache_namespace_uid, invalidation_namespace=invalidation_namespace)
with inv_context_manager as invalidation_context:
# check for stored invalidation signal, and maybe purge the cache
# before computing it again
args = (self.db_repo.repo_id, self.db_repo.repo_name, 'rss',)
# re-compute and store cache if we get invalidate signal
if invalidation_context.should_invalidate():
generate_rss_feed.invalidate(
self.db_repo.repo_id, self.db_repo.repo_name, 'rss')
mime_type, feed = generate_rss_feed(
self.db_repo.repo_id, self.db_repo.repo_name, 'rss')
mime_type, feed = generate_rss_feed.refresh(*args)
else:
mime_type, feed = generate_rss_feed(*args)
log.debug(
'Repo RSS feed computed in %.3fs', inv_context_manager.compute_time)

View file

@ -88,14 +88,12 @@ class RepoSummaryView(RepoAppView):
inv_context_manager = rc_cache.InvalidationContext(
uid=cache_namespace_uid, invalidation_namespace=invalidation_namespace)
with inv_context_manager as invalidation_context:
# check for stored invalidation signal, and maybe purge the cache
# before computing it again
args = (db_repo.repo_id, db_repo.repo_name, renderer_type,)
# re-compute and store cache if we get invalidate signal
if invalidation_context.should_invalidate():
generate_repo_readme.invalidate(
db_repo.repo_id, db_repo.repo_name, renderer_type)
instance = generate_repo_readme(
db_repo.repo_id, db_repo.repo_name, renderer_type)
instance = generate_repo_readme.refresh(*args)
else:
instance = generate_repo_readme(*args)
log.debug(
'Repo readme generated and computed in %.3fs',

View file

@ -227,14 +227,15 @@ class InvalidationContext(object):
inv_context_manager = rc_cache.InvalidationContext(
uid=cache_namespace_uid, invalidation_namespace=invalidation_namespace)
with inv_context_manager as invalidation_context:
# check for stored invalidation signal, and maybe purge the cache
# before computing it again
args = ('one', 'two')
# re-compute and store cache if we get invalidate signal
if invalidation_context.should_invalidate():
heavy_compute.invalidate('some_name', 'param1', 'param2')
result = heavy_compute.refresh(*args)
else:
result = heavy_compute(*args)
result = heavy_compute('some_name', 'param1', 'param2')
compute_time = inv_context_manager.compute_time
print(compute_time)
log.debug('result computed in %.3fs' ,compute_time)
# To send global invalidation signal, simply run
CacheKey.set_invalidate(invalidation_namespace)

View file

@ -2342,12 +2342,13 @@ class Repository(Base, BaseModel):
inv_context_manager = rc_cache.InvalidationContext(
uid=cache_namespace_uid, invalidation_namespace=invalidation_namespace)
with inv_context_manager as invalidation_context:
# check for stored invalidation signal, and maybe purge the cache
# before computing it again
args = (self.repo_id,)
# re-compute and store cache if we get invalidate signal
if invalidation_context.should_invalidate():
get_instance_cached.invalidate(self.repo_id)
instance = get_instance_cached.refresh(*args)
else:
instance = get_instance_cached(*args)
instance = get_instance_cached(self.repo_id)
log.debug(
'Repo instance fetched in %.3fs', inv_context_manager.compute_time)
return instance

View file

@ -583,8 +583,9 @@ def test_invalidation_context(baseapp):
with inv_context_manager as invalidation_context:
should_invalidate = invalidation_context.should_invalidate()
if should_invalidate:
_dummy_func.invalidate('some-key')
result = _dummy_func('some-key')
result = _dummy_func.refresh('some-key')
else:
result = _dummy_func('some-key')
assert isinstance(invalidation_context, rc_cache.FreshRegionCache)
assert should_invalidate is True
@ -608,8 +609,9 @@ def test_invalidation_context(baseapp):
with inv_context_manager as invalidation_context:
should_invalidate = invalidation_context.should_invalidate()
if should_invalidate:
_dummy_func.invalidate('some-key')
result = _dummy_func('some-key')
result = _dummy_func.refresh('some-key')
else:
result = _dummy_func('some-key')
assert isinstance(invalidation_context, rc_cache.FreshRegionCache)
assert should_invalidate is True
@ -642,8 +644,9 @@ def test_invalidation_context_exception_in_compute(baseapp):
with inv_context_manager as invalidation_context:
should_invalidate = invalidation_context.should_invalidate()
if should_invalidate:
_dummy_func.invalidate('some-key-2')
_dummy_func('some-key-2')
_dummy_func.refresh('some-key-2')
else:
_dummy_func('some-key-2')
@pytest.mark.parametrize('execution_number', range(5))
@ -674,8 +677,9 @@ def test_cache_invalidation_race_condition(execution_number, baseapp):
with inv_context_manager as invalidation_context:
should_invalidate = invalidation_context.should_invalidate()
if should_invalidate:
_dummy_func.invalidate('some-key-3')
_dummy_func('some-key-3')
_dummy_func.refresh('some-key-3')
else:
_dummy_func('some-key-3')
# Mark invalidation
CacheKey.set_invalidate(invalidation_namespace)