Permalink
Browse files

issue 3 - long urls cached

  • Loading branch information...
1 parent 9521cb0 commit 4f0c579461729e6cdacde3f92aaab6aaa6de0c99 @peterbe committed Mar 12, 2013
View
@@ -5,6 +5,16 @@
Changelog
=========
+v0.4.0 (2013-03-12)
+-------------------
+
+The function ``fancy_cache.memory.find_urls()`` can now be called
+without any arguments since means it matches *all* URLs.
+
+If you enable ``FANCY_REMEMBER_STATS_ALL_URLS`` and have some really
+big URLs (e.g. long query strings) you could get
+``MemcachedKeyLengthError`` errors potentially.
+
v0.3.2 (2013-02-13)
-------------------
View
@@ -1,2 +1,2 @@
-__version__ = '0.3.2'
+__version__ = '0.4.0'
from cache_page import cache_page
View
@@ -1,4 +1,5 @@
import re
+import hashlib
from django.core.cache import cache
@@ -7,6 +8,10 @@
__all__ = ('find_urls',)
+def md5(x):
+ return hashlib.md5(x).hexdigest()
+
+
def _match(url, regexes):
if not regexes:
return url
@@ -28,21 +33,24 @@ def _urls_to_regexes(urls):
return regexes
-def find_urls(urls, purge=False):
+def find_urls(urls=None, purge=False):
remembered_urls = cache.get(REMEMBERED_URLS_KEY, {})
_del_keys = []
- regexes = _urls_to_regexes(urls)
-
+ if urls:
+ regexes = _urls_to_regexes(urls)
for url in remembered_urls:
- if _match(url, regexes):
+ if not urls or _match(url, regexes):
cache_key = remembered_urls[url]
if not cache.get(cache_key):
continue
if purge:
cache.delete(cache_key)
_del_keys.append(url)
misses_cache_key = '%s__misses' % url
+ misses_cache_key = md5(misses_cache_key)
hits_cache_key = '%s__hits' % url
+ hits_cache_key = md5(hits_cache_key)
+
misses = cache.get(misses_cache_key)
hits = cache.get(hits_cache_key)
if misses is None and hits is None:
View
@@ -1,6 +1,7 @@
import cgi
import functools
import urllib
+import hashlib
from django.core.exceptions import ImproperlyConfigured
from django.conf import settings
@@ -18,6 +19,10 @@
LONG_TIME = 60 * 60 * 24 * 30
+def md5(x):
+ return hashlib.md5(x).hexdigest()
+
+
class RequestPath(object):
def __init__(self, request, only_get_keys):
self.request = request
@@ -152,6 +157,7 @@ def process_request(self, request):
cache_key += '__misses'
else:
cache_key += '__hits'
+ cache_key = md5(cache_key)
if cache.get(cache_key) is None:
cache.set(cache_key, 0, LONG_TIME)
cache.incr(cache_key)
@@ -174,15 +180,15 @@ def _process_request(self, request):
# Don't bother checking the cache.
return None
- if (
- request.GET and
- not callable(self.key_prefix) and
- not self.only_get_keys
- ):
- request._cache_update_cache = False
- # Default behaviour for requests with GET parameters: don't bother
- # checking the cache.
- return None
+ #if (
+ # request.GET and
+ # not callable(self.key_prefix) and
+ # not self.only_get_keys
+ #):
+ # request._cache_update_cache = False
+ # # Default behaviour for requests with GET parameters: don't bother
+ # # checking the cache.
+ # return None
if self.cache_anonymous_only and request.user.is_authenticated():
request._cache_update_cache = False
@@ -20,6 +20,9 @@ def setUp(self):
cache.set(value, key)
cache.set(REMEMBERED_URLS_KEY, self.urls, 5)
+ def tearDown(self):
+ cache.clear()
+
def test_find_all_urls(self):
found = list(find_urls([]))
eq_(len(found), 4)
@@ -2,6 +2,8 @@
import re
from nose.tools import eq_, ok_
from django.test.client import RequestFactory
+from django.core.cache import cache
+from fancy_cache.memory import find_urls
from . import views
@@ -11,6 +13,9 @@ class TestViews(unittest.TestCase):
def setUp(self):
self.factory = RequestFactory()
+ def tearDown(self):
+ cache.clear()
+
def test_render_home1(self):
request = self.factory.get('/anything')
@@ -116,3 +121,51 @@ def test_render_home5(self):
ok_(re.findall('Random:\w+', response.content))
random_string_3 = re.findall('Random:(\w+)', response.content)[0]
eq_(random_string_2, random_string_3)
+
+ def test_remember_stats_all_urls(self):
+ request = self.factory.get('/anything')
+ response = views.home6(request)
+ eq_(response.status_code, 200)
+
+ # now ask the memory thing
+ match, = find_urls('/anything')
+ eq_(match[0], '/anything')
+ eq_(match[2]['hits'], 0)
+ eq_(match[2]['misses'], 1)
+
+ # second time
+ response = views.home6(request)
+ eq_(response.status_code, 200)
+ match, = find_urls('/anything')
+ eq_(match[0], '/anything')
+ eq_(match[2]['hits'], 1)
+ eq_(match[2]['misses'], 1)
+
+ def test_remember_stats_all_urls_looong_url(self):
+ request = self.factory.get(
+ '/something/really/long/to/start/with/right/here/since/this/will/'
+ 'test/that/things/work/with/long/urls/too',
+ {
+ 'line1': 'Bad luck, wind been blowing at my back',
+ 'line2': "I was born to bring trouble to wherever I'm at",
+ 'line3': "Got the number thirteen, tattooed on my neck",
+ 'line4': "When the ink starts to itch, ",
+ 'line5': "then the black will turn to red",
+ }
+ )
+ response = views.home6(request)
+ eq_(response.status_code, 200)
+
+ # now ask the memory thing
+ match, = find_urls()
+ ok_(match[0].startswith('/something/really'))
+ eq_(match[2]['hits'], 0)
+ eq_(match[2]['misses'], 1)
+
+ # second time
+ response = views.home6(request)
+ eq_(response.status_code, 200)
+ match, = find_urls([])
+ ok_(match[0].startswith('/something/really'))
+ eq_(match[2]['hits'], 1)
+ eq_(match[2]['misses'], 1)
@@ -48,3 +48,8 @@ def home4(request):
@cache_page(60, only_get_keys=['foo', 'bar'])
def home5(request):
return _view(request)
+
+
+@cache_page(60, remember_stats_all_urls=True, remember_all_urls=True)
+def home6(request):
+ return _view(request)

0 comments on commit 4f0c579

Please sign in to comment.