summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan McGee <dan@archlinux.org>2010-10-08 02:33:52 +0200
committerDan McGee <dan@archlinux.org>2010-10-08 02:43:13 +0200
commitb2acd5cb94d0a675272048c1a3628152648911c1 (patch)
tree2ad9102aab22721be9acbf278359069a48e2fb19
parentcf7bf2de294a0e7be37f03935c0a292d60ed1829 (diff)
downloadarchweb-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.py25
1 files changed, 23 insertions, 2 deletions
diff --git a/feeds.py b/feeds.py
index c46a8be..ecb90b6 100644
--- a/feeds.py
+++ b/feeds.py
@@ -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: