Branch: refs/heads/master Author: Enrico Tröger enrico.troeger@uvena.de Committer: Enrico Tröger enrico.troeger@uvena.de Date: Sat, 31 Oct 2020 09:48:37 UTC Commit: 2039399e87b8e8fa766319dda7dbb6d164b93e8d https://github.com/geany/www.geany.org/commit/2039399e87b8e8fa766319dda7dbb6...
Log Message: ----------- Invalidate relevant cache items once a latest version is saved
Modified Paths: -------------- geany/decorators.py latest_version/context_processors.py latest_version/models.py static_docs/views.py
Modified: geany/decorators.py 40 lines changed, 24 insertions(+), 16 deletions(-) =================================================================== @@ -23,9 +23,12 @@ CACHE_TIMEOUT_24HOURS = 3600 * 24 CACHE_TIMEOUT_1HOUR = 3600
+CACHE_KEY_LATEST_VERSION_LATEST_VERSION = 'latest_version.latest_version' +CACHE_KEY_STATIC_DOCS_RELEASE_NOTES = 'static_docs.release_notes' +
# ---------------------------------------------------------------------- -def cache_function(timeout=900, ignore_arguments=False): +def cache_function(timeout=900, ignore_arguments=False, key=None): """ Cache the result of a function call for the specified number of seconds, using Django's caching mechanism. @@ -35,6 +38,9 @@ def cache_function(timeout=900, ignore_arguments=False): myFunction(x = 1, y = 2), myFunction(y = 2, x = 1), and myFunction(1,2) will each be cached separately.
+ If the keyword argument `key` is provided, automatic cache key generation is skipped + and the passed key is used instead (expected as string). + Usage:
@cache(600) @@ -44,23 +50,25 @@ def myExpensiveMethod(parm1, parm2, parm3): """ def do_cache(function): def wrapped(*args, **kwargs): - key = '%s.%s' % ((function.__module__, function.__name__)) - if args and not ignore_arguments: - cache_args = args - # don't include 'self' in arguments - arguments = inspect.getfullargspec(function) - if arguments and arguments.args[0] == 'self': - cache_args = args[1:] - if cache_args: - cache_args_repr = repr(cache_args).encode('utf-8') - key = '%s.args%s' % (key, hexlify(cache_args_repr)) - if kwargs and not ignore_arguments: - kwargs_repr = repr(kwargs).encode('utf-8') - key = '%s.kwargs%s' % (key, hexlify(kwargs_repr)) - result = _djcache.get(key) + cache_key = key + if cache_key is None: + cache_key = '%s.%s' % ((function.__module__, function.__name__)) + if args and not ignore_arguments: + cache_args = args + # don't include 'self' in arguments + arguments = inspect.getfullargspec(function) + if arguments and arguments.args[0] == 'self': + cache_args = args[1:] + if cache_args: + cache_args_repr = repr(cache_args).encode('utf-8') + cache_key = '%s.args%s' % (cache_key, hexlify(cache_args_repr)) + if kwargs and not ignore_arguments: + kwargs_repr = repr(kwargs).encode('utf-8') + cache_key = '%s.kwargs%s' % (cache_key, hexlify(kwargs_repr)) + result = _djcache.get(cache_key) if result is None: result = function(*args, **kwargs) - _djcache.set(key, result, timeout) + _djcache.set(cache_key, result, timeout) return result return wrapped return do_cache
Modified: latest_version/context_processors.py 8 lines changed, 6 insertions(+), 2 deletions(-) =================================================================== @@ -14,13 +14,17 @@
from mezzanine.conf import settings
-from geany.decorators import cache_function, CACHE_TIMEOUT_1HOUR +from geany.decorators import ( + cache_function, + CACHE_KEY_LATEST_VERSION_LATEST_VERSION, + CACHE_TIMEOUT_1HOUR, +) from latest_version.models import LatestVersion from latest_version.releases import ReleaseVersionsProvider
# ---------------------------------------------------------------------- -@cache_function(CACHE_TIMEOUT_1HOUR, ignore_arguments=True) +@cache_function(CACHE_TIMEOUT_1HOUR, key=CACHE_KEY_LATEST_VERSION_LATEST_VERSION) def latest_version(request): latest_versions = LatestVersion.objects.all() latest_versions_by_name = {
Modified: latest_version/models.py 13 lines changed, 13 insertions(+), 0 deletions(-) =================================================================== @@ -12,8 +12,14 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see http://www.gnu.org/licenses/.
+from django.core.cache import cache from django.db import models
+from geany.decorators import ( + CACHE_KEY_LATEST_VERSION_LATEST_VERSION, + CACHE_KEY_STATIC_DOCS_RELEASE_NOTES, +) +
class LatestVersion(models.Model):
@@ -33,6 +39,13 @@ class Meta: def delete(self, using=None, keep_parents=False): """Never delete anything"""
+ # ---------------------------------------------------------------------- + def save(self, *args, **kwargs): # pylint: disable=signature-differs + super().save(*args, **kwargs) + # invalidate related cached data + cache.delete_many( + [CACHE_KEY_LATEST_VERSION_LATEST_VERSION, CACHE_KEY_STATIC_DOCS_RELEASE_NOTES]) + # ---------------------------------------------------------------------- def __str__(self): return '{} {}'.format(self.name, self.version)
Modified: static_docs/views.py 9 lines changed, 7 insertions(+), 2 deletions(-) =================================================================== @@ -24,7 +24,12 @@ from django.views.generic.base import TemplateView from mezzanine_pagedown.filters import plain as markdown_plain
-from geany.decorators import cache_function, CACHE_TIMEOUT_1HOUR, CACHE_TIMEOUT_24HOURS +from geany.decorators import ( + cache_function, + CACHE_KEY_STATIC_DOCS_RELEASE_NOTES, + CACHE_TIMEOUT_1HOUR, + CACHE_TIMEOUT_24HOURS, +) from static_docs.github_client import GitHubApiClient
@@ -86,7 +91,7 @@ def get_context_data(self, **kwargs): return context
# ---------------------------------------------------------------------- - @cache_function(CACHE_TIMEOUT_24HOURS) + @cache_function(CACHE_TIMEOUT_24HOURS, key=CACHE_KEY_STATIC_DOCS_RELEASE_NOTES) def _get_release_notes(self): self._fetch_file_via_github_api('NEWS') return self._parse_news_file()
-------------- This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).