Skip to content

Commit

Permalink
Merge pull request #88 from lastfm/cope-with-cache-connection-errors
Browse files Browse the repository at this point in the history
Cope with cache connection errors
  • Loading branch information
jsocol committed Oct 14, 2015
2 parents 917d35f + fa3f0af commit 2b67dbc
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 18 deletions.
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ python:
- "3.4"
- "pypy"
install:
- if [[ $TRAVIS_PYTHON_VERSION == 2* ]]; then pip install -q python-memcached>=1.57; fi
- if [[ $TRAVIS_PYTHON_VERSION == 3* ]]; then pip install -q python3-memcached>=1.51; fi
- if [[ $TRAVIS_PYTHON_VERSION == pypy ]]; then pip install -q python-memcached>=1.57; fi
- pip install -q "Django>=${DJANGO_VERSION},<${DJANGO_VERSION}.99" flake8
script:
- ./run.sh test
Expand Down
37 changes: 37 additions & 0 deletions ratelimit/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,16 @@ def view(request):
with self.assertRaises(InvalidCacheBackendError):
view(req)

@override_settings(RATELIMIT_USE_CACHE='connection-errors')
def test_cache_connection_error(self):

@ratelimit(key='ip', rate='1/m')
def view(request):
return request

req = rf.post('/')
assert view(req)

def test_user_or_ip(self):
"""Allow custom functions to set cache keys."""

Expand Down Expand Up @@ -389,6 +399,33 @@ def do_increment(request):
assert do_increment(req), 'Request should be rate limited.'
assert not_increment(req), 'Request should be rate limited.'

@override_settings(RATELIMIT_USE_CACHE='connection-errors')
def test_is_ratelimited_cache_connection_error_without_increment(self):
def get_key(group, request):
return 'test_is_ratelimited_key'

def not_increment(request):
return is_ratelimited(request, increment=False,
method=is_ratelimited.ALL, key=get_key,
rate='1/m', group='a')

req = rf.get('/')
assert not not_increment(req)

@override_settings(RATELIMIT_USE_CACHE='connection-errors')
def test_is_ratelimited_cache_connection_error_with_increment(self):
def get_key(group, request):
return 'test_is_ratelimited_key'

def do_increment(request):
return is_ratelimited(request, increment=True,
method=is_ratelimited.ALL, key=get_key,
rate='1/m', group='a')

req = rf.get('/')
assert not do_increment(req)
assert req.limited is False


class RatelimitCBVTests(TestCase):

Expand Down
7 changes: 5 additions & 2 deletions ratelimit/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,12 @@ def is_ratelimited(request, group=None, fn=None, key=None, rate=None,
count = initial_value
else:
if increment:
count = cache.incr(cache_key)
try:
count = cache.incr(cache_key)
except ValueError:
count = 0
else:
count = cache.get(cache_key)
count = cache.get(cache_key) or 0
limited = count > limit
if increment:
request.limited = old_limited or limited
Expand Down
4 changes: 4 additions & 0 deletions test_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'ratelimit-tests',
},
'connection-errors': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': 'test-connection-errors',
},
}

DATABASES = {
Expand Down
64 changes: 48 additions & 16 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -5,70 +5,102 @@ commands = ./run.sh test

[testenv:py34-1.8]
basepython = python3.4
deps = Django>=1.8,<1.8.99
deps =
Django>=1.8,<1.8.99
python3-memcached>=1.51

[testenv:py34-1.7]
basepython = python3.4
deps = Django>=1.7,<1.7.99
deps =
Django>=1.7,<1.7.99
python3-memcached>=1.51

[testenv:py34-1.6]
basepython = python3.4
deps = Django>=1.6,<1.6.99
deps =
Django>=1.6,<1.6.99
python3-memcached>=1.51

[testenv:py34-1.5]
basepython = python3.4
deps = Django>=1.5,<1.5.99
deps =
Django>=1.5,<1.5.99
python3-memcached>=1.51

# python 3.3

[testenv:py33-1.8]
basepython = python3.3
deps = Django>=1.8,<1.8.99
deps =
Django>=1.8,<1.8.99
python3-memcached>=1.51

[testenv:py33-1.7]
basepython = python3.3
deps = Django>=1.7,<1.7.99
deps =
Django>=1.7,<1.7.99
python3-memcached>=1.51

[testenv:py33-1.6]
basepython = python3.3
deps = Django>=1.6,<1.6.99
deps =
Django>=1.6,<1.6.99
python3-memcached>=1.51

[testenv:py33-1.5]
basepython = python3.3
deps = Django>=1.5,<1.5.99
deps =
Django>=1.5,<1.5.99
python3-memcached>=1.51

# python 2.7

[testenv:py27-1.8]
basepython = python2.7
deps = Django>=1.7,<1.7.99
deps =
Django>=1.7,<1.7.99
python-memcached>=1.57

[testenv:py27-1.7]
basepython = python2.7
deps = Django>=1.7,<1.7.99
deps =
Django>=1.7,<1.7.99
python-memcached>=1.57

[testenv:py27-1.6]
basepython = python2.7
deps = Django>=1.6,<1.6.99
deps =
Django>=1.6,<1.6.99
python-memcached>=1.57

[testenv:py27-1.5]
basepython = python2.7
deps = Django>=1.5,<1.5.99
deps =
Django>=1.5,<1.5.99
python-memcached>=1.57

[testenv:py27-1.4]
basepython = python2.7
deps = Django>=1.4,<1.4.99
deps =
Django>=1.4,<1.4.99
python-memcached>=1.57

# python 2.6

[testenv:py26-1.6]
basepython = python2.6
deps = Django>=1.6,<1.6.99
deps =
Django>=1.6,<1.6.99
python-memcached>=1.57

[testenv:py26-1.5]
basepython = python2.6
deps = Django>=1.5,<1.5.99
deps =
Django>=1.5,<1.5.99
python-memcached>=1.57

[testenv:py26-1.4]
basepython = python2.6
deps = Django>=1.4,<1.4.99
deps =
Django>=1.4,<1.4.99
python-memcached>=1.57

0 comments on commit 2b67dbc

Please sign in to comment.