Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
D
Django-Redis-Cache
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Shared
Django-Redis-Cache
Commits
cc82dcf2
Commit
cc82dcf2
authored
Jul 20, 2015
by
Sean Bleier
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #88 from sebleier/unstable
Unstable
parents
5dc7a9e1
fb26ad82
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
221 additions
and
33 deletions
+221
-33
Makefile
Makefile
+1
-1
README.rst
README.rst
+6
-0
base.py
redis_cache/backends/base.py
+39
-30
compressors.py
redis_cache/compressors.py
+53
-0
utils.py
redis_cache/utils.py
+14
-0
setup.py
setup.py
+1
-1
compressor_tests.py
tests/testapp/tests/compressor_tests.py
+106
-0
socket_timeout_tests.py
tests/testapp/tests/socket_timeout_tests.py
+1
-1
No files found.
Makefile
View file @
cc82dcf2
...
@@ -21,7 +21,7 @@ clean:
...
@@ -21,7 +21,7 @@ clean:
.PHONY
:
test
.PHONY
:
test
test
:
install_requirements
test
:
install_requirements
PYTHONPATH
=
$(PYTHONPATH)
: django-admin.py
test
tests.testapp.tests.socket_timeout_tests:SocketTimeoutTestCase.test_socket_timeout
--settings
=
tests.settings
-s
PYTHONPATH
=
$(PYTHONPATH)
: django-admin.py
test
--settings
=
tests.settings
-s
.PHONY
:
shell
.PHONY
:
shell
shell
:
shell
:
...
...
README.rst
View file @
cc82dcf2
...
@@ -19,6 +19,12 @@ A Redis cache backend for Django
...
@@ -19,6 +19,12 @@ A Redis cache backend for Django
Changelog
Changelog
=========
=========
1.5.0
-----
* Adds ability to compress/decompress cache values using pluggable compressors
including zlib, bzip2, or a custom implementation.
1.4.0
1.4.0
-----
-----
...
...
redis_cache/backends/base.py
View file @
cc82dcf2
...
@@ -3,8 +3,6 @@ from django.core.exceptions import ImproperlyConfigured
...
@@ -3,8 +3,6 @@ from django.core.exceptions import ImproperlyConfigured
from
django.utils
import
importlib
from
django.utils
import
importlib
from
django.utils.importlib
import
import_module
from
django.utils.importlib
import
import_module
from
redis_cache.compat
import
smart_bytes
,
DEFAULT_TIMEOUT
try
:
try
:
import
redis
import
redis
except
ImportError
:
except
ImportError
:
...
@@ -14,8 +12,11 @@ except ImportError:
...
@@ -14,8 +12,11 @@ except ImportError:
from
redis.connection
import
DefaultParser
from
redis.connection
import
DefaultParser
from
redis_cache.compat
import
smart_bytes
,
DEFAULT_TIMEOUT
from
redis_cache.connection
import
pool
from
redis_cache.connection
import
pool
from
redis_cache.utils
import
CacheKey
,
get_servers
,
parse_connection_kwargs
from
redis_cache.utils
import
(
CacheKey
,
get_servers
,
parse_connection_kwargs
,
import_class
)
from
functools
import
wraps
from
functools
import
wraps
...
@@ -60,12 +61,21 @@ class BaseRedisCache(BaseCache):
...
@@ -60,12 +61,21 @@ class BaseRedisCache(BaseCache):
self
.
connection_pool_class_kwargs
=
(
self
.
connection_pool_class_kwargs
=
(
self
.
get_connection_pool_class_kwargs
()
self
.
get_connection_pool_class_kwargs
()
)
)
# Serializer
self
.
serializer_class
=
self
.
get_serializer_class
()
self
.
serializer_class
=
self
.
get_serializer_class
()
self
.
serializer_class_kwargs
=
self
.
get_serializer_class_kwargs
()
self
.
serializer_class_kwargs
=
self
.
get_serializer_class_kwargs
()
self
.
serializer
=
self
.
serializer_class
(
self
.
serializer
=
self
.
serializer_class
(
**
self
.
serializer_class_kwargs
**
self
.
serializer_class_kwargs
)
)
# Compressor
self
.
compressor_class
=
self
.
get_compressor_class
()
self
.
compressor_class_kwargs
=
self
.
get_compressor_class_kwargs
()
self
.
compressor
=
self
.
compressor_class
(
**
self
.
compressor_class_kwargs
)
def
__getstate__
(
self
):
def
__getstate__
(
self
):
return
{
'params'
:
self
.
params
,
'server'
:
self
.
server
}
return
{
'params'
:
self
.
params
,
'server'
:
self
.
server
}
...
@@ -83,18 +93,10 @@ class BaseRedisCache(BaseCache):
...
@@ -83,18 +93,10 @@ class BaseRedisCache(BaseCache):
return
self
.
params
.
get
(
'password'
,
self
.
options
.
get
(
'PASSWORD'
,
None
))
return
self
.
params
.
get
(
'password'
,
self
.
options
.
get
(
'PASSWORD'
,
None
))
def
get_parser_class
(
self
):
def
get_parser_class
(
self
):
cl
s
=
self
.
options
.
get
(
'PARSER_CLASS'
,
None
)
parser_clas
s
=
self
.
options
.
get
(
'PARSER_CLASS'
,
None
)
if
cl
s
is
None
:
if
parser_clas
s
is
None
:
return
DefaultParser
return
DefaultParser
mod_path
,
cls_name
=
cls
.
rsplit
(
'.'
,
1
)
return
import_class
(
parser_class
)
try
:
mod
=
importlib
.
import_module
(
mod_path
)
parser_class
=
getattr
(
mod
,
cls_name
)
except
AttributeError
:
raise
ImproperlyConfigured
(
"Could not find parser class '
%
s'"
%
parser_class
)
except
ImportError
as
ex
:
raise
ImproperlyConfigured
(
"Could not find module '
%
s'"
%
ex
)
return
parser_class
def
get_pickle_version
(
self
):
def
get_pickle_version
(
self
):
"""
"""
...
@@ -111,12 +113,7 @@ class BaseRedisCache(BaseCache):
...
@@ -111,12 +113,7 @@ class BaseRedisCache(BaseCache):
def
get_connection_pool_class
(
self
):
def
get_connection_pool_class
(
self
):
pool_class
=
self
.
options
.
get
(
'CONNECTION_POOL_CLASS'
,
'redis.ConnectionPool'
)
pool_class
=
self
.
options
.
get
(
'CONNECTION_POOL_CLASS'
,
'redis.ConnectionPool'
)
module_name
,
class_name
=
pool_class
.
rsplit
(
'.'
,
1
)
return
import_class
(
pool_class
)
module
=
import_module
(
module_name
)
try
:
return
getattr
(
module
,
class_name
)
except
AttributeError
:
raise
ImportError
(
'cannot import name
%
s'
%
class_name
)
def
get_connection_pool_class_kwargs
(
self
):
def
get_connection_pool_class_kwargs
(
self
):
return
self
.
options
.
get
(
'CONNECTION_POOL_CLASS_KWARGS'
,
{})
return
self
.
options
.
get
(
'CONNECTION_POOL_CLASS_KWARGS'
,
{})
...
@@ -126,16 +123,21 @@ class BaseRedisCache(BaseCache):
...
@@ -126,16 +123,21 @@ class BaseRedisCache(BaseCache):
'SERIALIZER_CLASS'
,
'SERIALIZER_CLASS'
,
'redis_cache.serializers.PickleSerializer'
'redis_cache.serializers.PickleSerializer'
)
)
module_name
,
class_name
=
serializer_class
.
rsplit
(
'.'
,
1
)
return
import_class
(
serializer_class
)
module
=
import_module
(
module_name
)
try
:
return
getattr
(
module
,
class_name
)
except
AttributeError
:
raise
ImportError
(
'cannot import name
%
s'
%
class_name
)
def
get_serializer_class_kwargs
(
self
):
def
get_serializer_class_kwargs
(
self
):
return
self
.
options
.
get
(
'SERIALIZER_CLASS_KWARGS'
,
{})
return
self
.
options
.
get
(
'SERIALIZER_CLASS_KWARGS'
,
{})
def
get_compressor_class
(
self
):
compressor_class
=
self
.
options
.
get
(
'COMPRESSOR_CLASS'
,
'redis_cache.compressors.NoopCompressor'
)
return
import_class
(
compressor_class
)
def
get_compressor_class_kwargs
(
self
):
return
self
.
options
.
get
(
'COMPRESSOR_CLASS_KWARGS'
,
{})
def
get_master_client
(
self
):
def
get_master_client
(
self
):
"""
"""
Get the write server:port of the master cache
Get the write server:port of the master cache
...
@@ -175,17 +177,25 @@ class BaseRedisCache(BaseCache):
...
@@ -175,17 +177,25 @@ class BaseRedisCache(BaseCache):
def
deserialize
(
self
,
value
):
def
deserialize
(
self
,
value
):
return
self
.
serializer
.
deserialize
(
value
)
return
self
.
serializer
.
deserialize
(
value
)
def
compress
(
self
,
value
):
return
self
.
compressor
.
compress
(
value
)
def
decompress
(
self
,
value
):
return
self
.
compressor
.
decompress
(
value
)
def
get_value
(
self
,
original
):
def
get_value
(
self
,
original
):
try
:
try
:
value
=
int
(
original
)
value
=
int
(
original
)
except
(
ValueError
,
TypeError
):
except
(
ValueError
,
TypeError
):
value
=
self
.
deserialize
(
original
)
value
=
self
.
decompress
(
original
)
value
=
self
.
deserialize
(
value
)
return
value
return
value
def
prep_value
(
self
,
value
):
def
prep_value
(
self
,
value
):
if
isinstance
(
value
,
int
)
and
not
isinstance
(
value
,
bool
):
if
isinstance
(
value
,
int
)
and
not
isinstance
(
value
,
bool
):
return
value
return
value
return
self
.
serialize
(
value
)
value
=
self
.
serialize
(
value
)
return
self
.
compress
(
value
)
def
make_key
(
self
,
key
,
version
=
None
):
def
make_key
(
self
,
key
,
version
=
None
):
if
not
isinstance
(
key
,
CacheKey
):
if
not
isinstance
(
key
,
CacheKey
):
...
@@ -382,8 +392,7 @@ class BaseRedisCache(BaseCache):
...
@@ -382,8 +392,7 @@ class BaseRedisCache(BaseCache):
keys
=
client
.
keys
(
'*'
)
keys
=
client
.
keys
(
'*'
)
for
key
in
keys
:
for
key
in
keys
:
timeout
=
client
.
ttl
(
key
)
timeout
=
client
.
ttl
(
key
)
value
=
self
.
deserialize
(
client
.
get
(
key
))
value
=
self
.
get_value
(
client
.
get
(
key
))
if
timeout
is
None
:
if
timeout
is
None
:
client
.
set
(
key
,
self
.
prep_value
(
value
))
client
.
set
(
key
,
self
.
prep_value
(
value
))
...
...
redis_cache/compressors.py
0 → 100644
View file @
cc82dcf2
import
zlib
try
:
import
bz2
except
ImportError
:
pass
class
BaseCompressor
(
object
):
def
__init__
(
self
,
**
kwargs
):
super
(
BaseCompressor
,
self
)
.
__init__
()
def
compress
(
self
,
value
):
raise
NotImplementedError
def
decompress
(
self
,
value
):
raise
NotImplementedError
class
NoopCompressor
(
BaseCompressor
):
def
compress
(
self
,
value
):
return
value
def
decompress
(
self
,
value
):
return
value
class
ZLibCompressor
(
BaseCompressor
):
def
__init__
(
self
,
level
=
6
):
self
.
level
=
level
super
(
ZLibCompressor
,
self
)
.
__init__
()
def
compress
(
self
,
value
):
return
zlib
.
compress
(
value
,
self
.
level
)
def
decompress
(
self
,
value
):
return
zlib
.
decompress
(
value
)
class
BZip2Compressor
(
BaseCompressor
):
def
__init__
(
self
,
compresslevel
=
9
):
self
.
compresslevel
=
compresslevel
super
(
BZip2Compressor
,
self
)
.
__init__
()
def
compress
(
self
,
value
):
return
bz2
.
compress
(
value
,
compresslevel
=
self
.
compresslevel
)
def
decompress
(
self
,
value
):
return
bz2
.
decompress
(
value
)
redis_cache/utils.py
View file @
cc82dcf2
import
warnings
import
warnings
from
django.core.exceptions
import
ImproperlyConfigured
from
django.core.exceptions
import
ImproperlyConfigured
from
django.utils.importlib
import
import_module
from
redis.connection
import
SSLConnection
from
redis.connection
import
SSLConnection
from
redis_cache.compat
import
(
from
redis_cache.compat
import
(
...
@@ -49,6 +50,19 @@ def get_servers(location):
...
@@ -49,6 +50,19 @@ def get_servers(location):
return
servers
return
servers
def
import_class
(
path
):
module_name
,
class_name
=
path
.
rsplit
(
'.'
,
1
)
try
:
module
=
import_module
(
module_name
)
except
ImportError
:
raise
ImproperlyConfigured
(
'Could not find module "
%
s"'
%
module_name
)
else
:
try
:
return
getattr
(
module
,
class_name
)
except
AttributeError
:
raise
ImproperlyConfigured
(
'Cannot import "
%
s"'
%
class_name
)
def
parse_connection_kwargs
(
server
,
db
=
None
,
**
kwargs
):
def
parse_connection_kwargs
(
server
,
db
=
None
,
**
kwargs
):
"""
"""
Return a connection pool configured from the given URL.
Return a connection pool configured from the given URL.
...
...
setup.py
View file @
cc82dcf2
...
@@ -5,7 +5,7 @@ setup(
...
@@ -5,7 +5,7 @@ setup(
url
=
"http://github.com/sebleier/django-redis-cache/"
,
url
=
"http://github.com/sebleier/django-redis-cache/"
,
author
=
"Sean Bleier"
,
author
=
"Sean Bleier"
,
author_email
=
"sebleier@gmail.com"
,
author_email
=
"sebleier@gmail.com"
,
version
=
"1.
4.0
"
,
version
=
"1.
5.1
"
,
packages
=
[
"redis_cache"
,
"redis_cache.backends"
],
packages
=
[
"redis_cache"
,
"redis_cache.backends"
],
description
=
"Redis Cache Backend for Django"
,
description
=
"Redis Cache Backend for Django"
,
install_requires
=
[
'redis>=2.10.3'
],
install_requires
=
[
'redis>=2.10.3'
],
...
...
tests/testapp/tests/compressor_tests.py
0 → 100644
View file @
cc82dcf2
# -*- coding: utf-8 -*-
try
:
from
django.test
import
override_settings
except
ImportError
:
from
django.test.utils
import
override_settings
from
django.test
import
TestCase
from
tests.testapp.tests.base_tests
import
BaseRedisTestCase
LOCATION
=
"127.0.0.1:6381"
class
CompressionTestCase
(
object
):
def
test_compression
(
self
):
key
=
'a'
noop_cache
=
self
.
get_cache
(
'noop'
)
string
=
10000
*
'a'
self
.
cache
.
set
(
key
,
string
)
noop_cache
.
set
(
key
,
string
)
self
.
assertEqual
(
self
.
cache
.
get
(
key
),
noop_cache
.
get
(
key
))
self
.
assertNotEqual
(
self
.
cache
,
noop_cache
)
noop_client
,
=
list
(
noop_cache
.
clients
.
values
())
default_client
,
=
list
(
self
.
cache
.
clients
.
values
())
versioned_key
=
self
.
cache
.
make_key
(
key
)
self
.
assertLess
(
len
(
default_client
.
get
(
versioned_key
)),
len
(
noop_client
.
get
(
versioned_key
)),
)
@
override_settings
(
CACHES
=
{
'default'
:
{
'BACKEND'
:
'redis_cache.RedisCache'
,
'LOCATION'
:
LOCATION
,
'OPTIONS'
:
{
'DB'
:
14
,
'PASSWORD'
:
'yadayada'
,
'PARSER_CLASS'
:
'redis.connection.HiredisParser'
,
'PICKLE_VERSION'
:
-
1
,
'COMPRESSOR_CLASS'
:
'redis_cache.compressors.ZLibCompressor'
,
'COMPRESSOR_CLASS_KWARGS'
:
{
'level'
:
5
,
},
'CONNECTION_POOL_CLASS'
:
'redis.ConnectionPool'
,
'CONNECTION_POOL_CLASS_KWARGS'
:
{
'max_connections'
:
2
,
},
},
},
'noop'
:
{
'BACKEND'
:
'redis_cache.RedisCache'
,
'LOCATION'
:
LOCATION
,
'OPTIONS'
:
{
'DB'
:
15
,
'PASSWORD'
:
'yadayada'
,
'PARSER_CLASS'
:
'redis.connection.HiredisParser'
,
'PICKLE_VERSION'
:
-
1
,
'COMPRESSOR_CLASS'
:
'redis_cache.compressors.NoopCompressor'
,
},
},
}
)
class
ZLibTestCase
(
CompressionTestCase
,
BaseRedisTestCase
,
TestCase
):
pass
@
override_settings
(
CACHES
=
{
'default'
:
{
'BACKEND'
:
'redis_cache.RedisCache'
,
'LOCATION'
:
LOCATION
,
'OPTIONS'
:
{
'DB'
:
14
,
'PASSWORD'
:
'yadayada'
,
'PARSER_CLASS'
:
'redis.connection.HiredisParser'
,
'PICKLE_VERSION'
:
-
1
,
'COMPRESSOR_CLASS'
:
'redis_cache.compressors.BZip2Compressor'
,
'COMPRESSOR_CLASS_KWARGS'
:
{
'compresslevel'
:
5
,
},
'CONNECTION_POOL_CLASS'
:
'redis.ConnectionPool'
,
'CONNECTION_POOL_CLASS_KWARGS'
:
{
'max_connections'
:
2
,
},
},
},
'noop'
:
{
'BACKEND'
:
'redis_cache.RedisCache'
,
'LOCATION'
:
LOCATION
,
'OPTIONS'
:
{
'DB'
:
15
,
'PASSWORD'
:
'yadayada'
,
'PARSER_CLASS'
:
'redis.connection.HiredisParser'
,
'PICKLE_VERSION'
:
-
1
,
'COMPRESSOR_CLASS'
:
'redis_cache.compressors.NoopCompressor'
,
},
},
}
)
class
BZip2TestCase
(
CompressionTestCase
,
BaseRedisTestCase
,
TestCase
):
pass
tests/testapp/tests/socket_timeout_tests.py
View file @
cc82dcf2
...
@@ -8,7 +8,7 @@ from django.test import TestCase
...
@@ -8,7 +8,7 @@ from django.test import TestCase
from
redis.exceptions
import
ConnectionError
from
redis.exceptions
import
ConnectionError
from
tests.testapp.tests.base_tests
import
SetupMixin
from
tests.testapp.tests.base_tests
import
SetupMixin
LOCATION
=
"127.0.0.1:638
2
"
LOCATION
=
"127.0.0.1:638
1
"
@
override_settings
(
@
override_settings
(
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment