diff options
author | Dan McGee <dan@archlinux.org> | 2010-10-08 02:33:52 +0200 |
---|---|---|
committer | Dan McGee <dan@archlinux.org> | 2010-10-08 02:43:13 +0200 |
commit | b2acd5cb94d0a675272048c1a3628152648911c1 (patch) | |
tree | 2ad9102aab22721be9acbf278359069a48e2fb19 | |
parent | cf7bf2de294a0e7be37f03935c0a292d60ed1829 (diff) | |
download | archweb-b2acd5cb94d0a675272048c1a3628152648911c1.tar.gz archweb-b2acd5cb94d0a675272048c1a3628152648911c1.tar.xz |
Store latest news date in memcached
This saves two database queries each request, meaning no database hits at
all if we are just going to return a 304 response. It also requires adding a
post_save signal to ensure our cache is updated with the correct latest news
date upon saving a news item.
Signed-off-by: Dan McGee <dan@archlinux.org>
-rw-r--r-- | feeds.py | 25 |
1 files changed, 23 insertions, 2 deletions
@@ -1,13 +1,18 @@ import datetime from django.contrib.syndication.views import Feed +from django.core.cache import cache from django.db.models import Q +from django.db.models.signals import post_save from django.utils.hashcompat import md5_constructor from django.views.decorators.http import condition from main.models import Arch, Repo, Package from news.models import News +CACHE_TIMEOUT = 1800 +CACHE_NEWS_KEY = 'cache_news_latest' + def package_etag(request, *args, **kwargs): latest = Package.objects.latest('last_update') if latest: @@ -79,13 +84,26 @@ class PackageFeed(Feed): def retrieve_news_latest(): + latest = cache.get(CACHE_NEWS_KEY) + if latest: + return latest try: - latest = News.objects.values('last_modified').latest('last_modified') - return latest['last_modified'] + latest = News.objects.values('last_modified').latest( + 'last_modified')['last_modified'] + cache.set(CACHE_NEWS_KEY, latest, CACHE_TIMEOUT) + return latest except News.DoesNotExist: pass return None +def refresh_news_latest(**kwargs): + # We could delete the value, but that could open a race condition + # where the new data wouldn't have been committed yet by the calling + # thread. Update it instead. + latest = News.objects.values('last_modified').latest( + 'last_modified')['last_modified'] + cache.set(CACHE_NEWS_KEY, latest, CACHE_TIMEOUT) + def news_etag(request, *args, **kwargs): latest = retrieve_news_latest() if latest: @@ -116,4 +134,7 @@ class NewsFeed(Feed): def item_author_name(self, item): return item.author.get_full_name() +# connect signals needed to keep cache in line with reality +post_save.connect(refresh_news_latest, sender=News) + # vim: set ts=4 sw=4 et: |