Skip to content

Commit

Permalink
feat: cache codemeta json string for quicker page loads
Browse files Browse the repository at this point in the history
introduces a simple scheme for caching properties of a codebase or
release that get invalidated every time the codebase or release are
updated
  • Loading branch information
sgfost committed Dec 21, 2024
1 parent f2cfcea commit 8687193
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 9 deletions.
37 changes: 34 additions & 3 deletions django/library/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -802,6 +802,15 @@ def create_git_mirror(self, repository_name, **kwargs):
self.save()
return self.git_mirror

@property
def invalidate_on_save_cache_prefix(self):
"""prefix for cache keys that should be invalidated on save"""
return f"codebase:{self.id}"

def invalidate_cached_properties(self):
keys = cache.keys(f"{self.invalidate_on_save_cache_prefix}:*")
cache.delete_many(keys)

@property
def codebase_contributors_redis_key(self):
return f"codebase:contributors:{self.identifier}"
Expand Down Expand Up @@ -1715,7 +1724,6 @@ def common_metadata(self):
return CommonMetadata(self)

# FIXME: is there any reason for this to be a cached property?
# the json string that gets used in the page could benefit from being *globally* cached though
# it may also be wise to have a minimal codemeta dict that gets generated in case of an exception
# when using codemeticulous
@cached_property
Expand Down Expand Up @@ -1784,8 +1792,31 @@ def get_status_color(self):
return COLOR_MAP.get(self.status)

@property
def codemeta_json(self):
return self.codemeta.json()
def invalidate_on_save_cache_prefix(self):
"""prefix for cache keys that should be invalidated on save"""
return f"{self.codebase.invalidate_on_save_cache_prefix}:release:{self.id}"

def invalidate_cached_properties(self):
keys = cache.keys(f"{self.invalidate_on_save_cache_prefix}:*")
cache.delete_many(keys)

@property
def codemeta_json(self) -> str:
"""Returns the codemeta json string for this release. This property
is cached for 30 days to reduce page load times. The cache gets invalidated
every time the release or parent codebase is updated (post-save signal handler).
Use codemeta.json() instead to re-generate"""
key = f"{self.invalidate_on_save_cache_prefix}:codemeta_json"
json_str = cache.get(key)
if json_str is None:
json_str = self.codemeta.json()
cache.set(
key,
json_str,
timeout=60 * 60 * 24 * 30,
)
return json_str

def create_or_update_codemeta(self, force=True):
return self.get_fs_api().create_or_update_codemeta(force=force)
Expand Down
17 changes: 11 additions & 6 deletions django/library/signals.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import logging
import shortuuid

from django.conf import settings
from django.core.cache import cache
from django.db.models.signals import post_save
from django.dispatch import receiver

Expand All @@ -16,10 +15,13 @@
)
def on_codebase_release_save(sender, instance: CodebaseRelease, **kwargs):
"""
update the metadata in the git mirror for a codebase release if it has a git mirror
and the metadata changed
* update the metadata in the git mirror for a codebase release if it has a git mirror
and the metadata changed
* invalidate any cached properties for this release with the invalidation prefix
"""
release = instance
release.invalidate_cached_properties()

codebase = release.codebase
mirror = codebase.git_mirror
if mirror and mirror.remote_url:
Expand All @@ -29,10 +31,13 @@ def on_codebase_release_save(sender, instance: CodebaseRelease, **kwargs):
@receiver(post_save, sender=Codebase, dispatch_uid="update_mirrored_codebase_metadata")
def on_codebase_save(sender, instance: Codebase, **kwargs):
"""
update the metadata in the git mirror for a codebase if it has a git mirror
and the metadata changed
* update the metadata in the git mirror for a codebase if it has a git mirror
and the metadata changed
* invalidate any cached properties for this codebase with the invalidation prefix
"""
codebase = instance
codebase.invalidate_cached_properties()

mirror = codebase.git_mirror
if mirror and mirror.remote_url:
update_mirrored_codebase_metadata(codebase.id)

0 comments on commit 8687193

Please sign in to comment.