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
f88925a1
Commit
f88925a1
authored
Jun 25, 2015
by
Sean Bleier
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move master-slave setup to default cache backend and refactor a bit.
parent
a8b809a8
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
149 additions
and
304 deletions
+149
-304
base.py
redis_cache/backends/base.py
+108
-105
multiple.py
redis_cache/backends/multiple.py
+17
-116
single.py
redis_cache/backends/single.py
+23
-82
master_slave_tests.py
tests/testapp/tests/master_slave_tests.py
+1
-1
No files found.
redis_cache/backends/base.py
View file @
f88925a1
...
@@ -4,7 +4,7 @@ from django.utils import importlib
...
@@ -4,7 +4,7 @@ from django.utils import importlib
from
django.utils.functional
import
cached_property
from
django.utils.functional
import
cached_property
from
django.utils.importlib
import
import_module
from
django.utils.importlib
import
import_module
from
redis_cache.compat
import
smart_bytes
,
DEFAULT_TIMEOUT
from
redis_cache.compat
import
bytes_type
,
smart_bytes
,
DEFAULT_TIMEOUT
try
:
try
:
import
cPickle
as
pickle
import
cPickle
as
pickle
...
@@ -22,6 +22,26 @@ from redis_cache.connection import pool
...
@@ -22,6 +22,26 @@ from redis_cache.connection import pool
from
redis_cache.utils
import
CacheKey
from
redis_cache.utils
import
CacheKey
from
functools
import
wraps
def
get_client
(
write
=
False
):
def
wrapper
(
method
):
@
wraps
(
method
)
def
wrapped
(
self
,
key
,
*
args
,
**
kwargs
):
version
=
kwargs
.
pop
(
'version'
,
None
)
client
=
self
.
get_client
(
key
,
write
=
write
)
key
=
self
.
make_key
(
key
,
version
=
version
)
return
method
(
self
,
client
,
key
,
*
args
,
**
kwargs
)
return
wrapped
return
wrapper
class
BaseRedisCache
(
BaseCache
):
class
BaseRedisCache
(
BaseCache
):
def
__init__
(
self
,
server
,
params
):
def
__init__
(
self
,
server
,
params
):
...
@@ -30,15 +50,20 @@ class BaseRedisCache(BaseCache):
...
@@ -30,15 +50,20 @@ class BaseRedisCache(BaseCache):
"""
"""
super
(
BaseRedisCache
,
self
)
.
__init__
(
params
)
super
(
BaseRedisCache
,
self
)
.
__init__
(
params
)
self
.
server
=
server
self
.
server
=
server
self
.
servers
=
self
.
get_servers
(
server
)
self
.
params
=
params
or
{}
self
.
params
=
params
or
{}
self
.
options
=
params
.
get
(
'OPTIONS'
,
{})
self
.
options
=
params
.
get
(
'OPTIONS'
,
{})
self
.
clients
=
{}
self
.
client_list
=
[]
self
.
db
=
self
.
get_db
()
self
.
db
=
self
.
get_db
()
self
.
password
=
self
.
get_password
()
self
.
password
=
self
.
get_password
()
self
.
parser_class
=
self
.
get_parser_class
()
self
.
parser_class
=
self
.
get_parser_class
()
self
.
pickle_version
=
self
.
get_pickle_version
()
self
.
pickle_version
=
self
.
get_pickle_version
()
self
.
connection_pool_class
=
self
.
get_connection_pool_class
()
self
.
connection_pool_class
=
self
.
get_connection_pool_class
()
self
.
connection_pool_class_kwargs
=
self
.
get_connection_pool_class_kwargs
()
self
.
connection_pool_class_kwargs
=
(
self
.
get_connection_pool_class_kwargs
()
)
def
__getstate__
(
self
):
def
__getstate__
(
self
):
return
{
'params'
:
self
.
params
,
'server'
:
self
.
server
}
return
{
'params'
:
self
.
params
,
'server'
:
self
.
server
}
...
@@ -46,6 +71,20 @@ class BaseRedisCache(BaseCache):
...
@@ -46,6 +71,20 @@ class BaseRedisCache(BaseCache):
def
__setstate__
(
self
,
state
):
def
__setstate__
(
self
,
state
):
self
.
__init__
(
**
state
)
self
.
__init__
(
**
state
)
def
get_servers
(
self
,
server
):
"""returns a list of servers given the server argument passed in
from Django.
"""
if
isinstance
(
server
,
bytes_type
):
servers
=
server
.
split
(
','
)
elif
hasattr
(
server
,
'__iter__'
):
servers
=
server
else
:
raise
ImproperlyConfigured
(
'"server" must be an iterable or string'
)
return
servers
def
get_db
(
self
):
def
get_db
(
self
):
_db
=
self
.
params
.
get
(
'db'
,
self
.
options
.
get
(
'DB'
,
1
))
_db
=
self
.
params
.
get
(
'db'
,
self
.
options
.
get
(
'DB'
,
1
))
try
:
try
:
...
@@ -92,6 +131,13 @@ class BaseRedisCache(BaseCache):
...
@@ -92,6 +131,13 @@ class BaseRedisCache(BaseCache):
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'
,
{})
def
get_master_client
(
self
):
"""
Get the write server:port of the master cache
"""
cache
=
self
.
options
.
get
(
'MASTER_CACHE'
,
None
)
return
self
.
client_list
[
0
]
if
cache
is
None
else
self
.
create_client
(
cache
)
def
create_client
(
self
,
server
):
def
create_client
(
self
,
server
):
kwargs
=
{
kwargs
=
{
'db'
:
self
.
db
,
'db'
:
self
.
db
,
...
@@ -172,33 +218,27 @@ class BaseRedisCache(BaseCache):
...
@@ -172,33 +218,27 @@ class BaseRedisCache(BaseCache):
# Django cache api #
# Django cache api #
####################
####################
def
_add
(
self
,
client
,
key
,
value
,
timeout
):
@
get_client
(
write
=
True
)
return
self
.
_set
(
key
,
value
,
timeout
,
client
,
_add_only
=
True
)
def
add
(
self
,
client
,
key
,
value
,
timeout
=
None
):
"""Add a value to the cache, failing if the key already exists.
def
add
(
self
,
key
,
value
,
timeout
=
None
,
version
=
None
):
"""
Add a value to the cache, failing if the key already exists.
Returns ``True`` if the object was added, ``False`` if not.
Returns ``True`` if the object was added, ``False`` if not.
"""
"""
raise
NotImplementedError
return
self
.
_set
(
client
,
key
,
self
.
prep_value
(
value
),
timeout
,
_add_only
=
True
)
@
get_client
()
def
get
(
self
,
client
,
key
,
default
=
None
):
"""Retrieve a value from the cache.
def
_get
(
self
,
client
,
key
,
default
=
None
):
Returns deserialized value if key is found, the default if not.
"""
value
=
client
.
get
(
key
)
value
=
client
.
get
(
key
)
if
value
is
None
:
if
value
is
None
:
return
default
return
default
value
=
self
.
get_value
(
value
)
value
=
self
.
get_value
(
value
)
return
value
return
value
def
get
(
self
,
key
,
default
=
None
,
version
=
None
):
def
_set
(
self
,
client
,
key
,
value
,
timeout
,
_add_only
=
False
):
"""
Retrieve a value from the cache.
Returns unpickled value if key is found, the default if not.
"""
raise
NotImplementedError
def
__set
(
self
,
client
,
key
,
value
,
timeout
,
_add_only
=
False
):
if
timeout
is
None
or
timeout
==
0
:
if
timeout
is
None
or
timeout
==
0
:
if
_add_only
:
if
_add_only
:
return
client
.
setnx
(
key
,
value
)
return
client
.
setnx
(
key
,
value
)
...
@@ -213,36 +253,24 @@ class BaseRedisCache(BaseCache):
...
@@ -213,36 +253,24 @@ class BaseRedisCache(BaseCache):
else
:
else
:
return
False
return
False
def
_set
(
self
,
key
,
value
,
timeout
=
DEFAULT_TIMEOUT
,
client
=
None
,
_add_only
=
False
):
@
get_client
(
write
=
True
)
"""
def
set
(
self
,
client
,
key
,
value
,
timeout
=
DEFAULT_TIMEOUT
):
Persist a value to the cache, and set an optional expiration time.
"""
Persist a value to the cache, and set an optional expiration time.
"""
"""
if
timeout
is
DEFAULT_TIMEOUT
:
if
timeout
is
DEFAULT_TIMEOUT
:
timeout
=
self
.
default_timeout
timeout
=
self
.
default_timeout
if
timeout
is
not
None
:
if
timeout
is
not
None
:
timeout
=
int
(
timeout
)
timeout
=
int
(
timeout
)
# If ``value`` is not an int, then pickle it
if
not
isinstance
(
value
,
int
)
or
isinstance
(
value
,
bool
):
result
=
self
.
__set
(
client
,
key
,
pickle
.
dumps
(
value
),
timeout
,
_add_only
)
else
:
result
=
self
.
__set
(
client
,
key
,
value
,
timeout
,
_add_only
)
# result is a boolean
return
result
def
set
(
self
,
key
,
value
,
timeout
=
None
,
version
=
None
,
client
=
None
):
result
=
self
.
_set
(
client
,
key
,
self
.
prep_value
(
value
),
timeout
,
_add_only
=
False
)
"""
Persist a value to the cache, and set an optional expiration time.
"""
raise
NotImplementedError
()
def
_delete
(
self
,
client
,
key
):
return
result
return
client
.
delete
(
key
)
def
delete
(
self
,
key
,
version
=
None
):
@
get_client
(
write
=
True
)
"""
def
delete
(
self
,
client
,
key
):
Remove a key from the cache.
"""Remove a key from the cache."""
"""
return
client
.
delete
(
key
)
raise
NotImplementedError
def
_delete_many
(
self
,
client
,
keys
):
def
_delete_many
(
self
,
client
,
keys
):
return
client
.
delete
(
*
keys
)
return
client
.
delete
(
*
keys
)
...
@@ -257,8 +285,7 @@ class BaseRedisCache(BaseCache):
...
@@ -257,8 +285,7 @@ class BaseRedisCache(BaseCache):
return
client
.
flushdb
()
return
client
.
flushdb
()
def
clear
(
self
,
version
=
None
):
def
clear
(
self
,
version
=
None
):
"""
"""Flush cache keys.
Flush cache keys.
If version is specified, all keys belonging the version's key
If version is specified, all keys belonging the version's key
namespace will be deleted. Otherwise, all keys will be deleted.
namespace will be deleted. Otherwise, all keys will be deleted.
...
@@ -266,9 +293,6 @@ class BaseRedisCache(BaseCache):
...
@@ -266,9 +293,6 @@ class BaseRedisCache(BaseCache):
raise
NotImplementedError
raise
NotImplementedError
def
_get_many
(
self
,
client
,
original_keys
,
versioned_keys
):
def
_get_many
(
self
,
client
,
original_keys
,
versioned_keys
):
"""
Retrieve many keys.
"""
recovered_data
=
{}
recovered_data
=
{}
map_keys
=
dict
(
zip
(
versioned_keys
,
original_keys
))
map_keys
=
dict
(
zip
(
versioned_keys
,
original_keys
))
...
@@ -282,18 +306,14 @@ class BaseRedisCache(BaseCache):
...
@@ -282,18 +306,14 @@ class BaseRedisCache(BaseCache):
return
recovered_data
return
recovered_data
def
get_many
(
self
,
keys
,
version
=
None
):
def
get_many
(
self
,
keys
,
version
=
None
):
"""Retrieve many keys."""
raise
NotImplementedError
raise
NotImplementedError
def
_set_many
(
self
,
client
,
data
):
def
_set_many
(
self
,
client
,
data
):
new_data
=
{}
return
client
.
mset
(
data
)
for
key
,
value
in
data
.
items
():
new_data
[
key
]
=
self
.
prep_value
(
value
)
return
client
.
mset
(
new_data
)
def
set_many
(
self
,
data
,
timeout
=
None
,
version
=
None
):
def
set_many
(
self
,
data
,
timeout
=
None
,
version
=
None
):
"""
"""Set a bunch of values in the cache at once from a dict of key/value
Set a bunch of values in the cache at once from a dict of key/value
pairs. This is much more efficient than calling set() multiple times.
pairs. This is much more efficient than calling set() multiple times.
If timeout is given, that timeout will be used for the key; otherwise
If timeout is given, that timeout will be used for the key; otherwise
...
@@ -301,37 +321,32 @@ class BaseRedisCache(BaseCache):
...
@@ -301,37 +321,32 @@ class BaseRedisCache(BaseCache):
"""
"""
raise
NotImplementedError
raise
NotImplementedError
def
_incr
(
self
,
client
,
key
,
delta
=
1
):
@
get_client
(
write
=
True
)
def
incr
(
self
,
client
,
key
,
delta
=
1
):
"""Add delta to value in the cache. If the key does not exist, raise a
`ValueError` exception.
"""
exists
=
client
.
exists
(
key
)
exists
=
client
.
exists
(
key
)
if
not
exists
:
if
not
exists
:
raise
ValueError
(
"Key '
%
s' not found"
%
key
)
raise
ValueError
(
"Key '
%
s' not found"
%
key
)
try
:
try
:
value
=
client
.
incr
(
key
,
delta
)
value
=
client
.
incr
(
key
,
delta
)
except
redis
.
ResponseError
:
except
redis
.
ResponseError
:
value
=
self
.
_get
(
client
,
key
)
+
delta
key
=
key
.
_original_key
self
.
_set
(
client
,
key
,
value
,
timeout
=
None
)
value
=
self
.
get
(
key
)
+
delta
self
.
set
(
key
,
value
,
timeout
=
None
)
return
value
return
value
def
incr
(
self
,
key
,
delta
=
1
,
version
=
None
):
"""
Add delta to value in the cache. If the key does not exist, raise a
ValueError exception.
"""
raise
NotImplementedError
def
_incr_version
(
self
,
client
,
old
,
new
,
delta
,
version
):
def
_incr_version
(
self
,
client
,
old
,
new
,
delta
,
version
):
try
:
try
:
client
.
rename
(
old
,
new
)
client
.
rename
(
old
,
new
)
except
redis
.
ResponseError
:
except
redis
.
ResponseError
:
raise
ValueError
(
"Key '
%
s' not found"
%
old
.
_original_key
)
raise
ValueError
(
"Key '
%
s' not found"
%
old
.
_original_key
)
return
version
+
delta
return
version
+
delta
def
incr_version
(
self
,
key
,
delta
=
1
,
version
=
None
):
def
incr_version
(
self
,
key
,
delta
=
1
,
version
=
None
):
"""
"""Adds delta to the cache version for the supplied key. Returns the
Adds delta to the cache version for the supplied key. Returns the
new version.
new version.
"""
"""
raise
NotImplementedError
raise
NotImplementedError
...
@@ -339,28 +354,22 @@ class BaseRedisCache(BaseCache):
...
@@ -339,28 +354,22 @@ class BaseRedisCache(BaseCache):
# Extra api methods #
# Extra api methods #
#####################
#####################
def
_has_key
(
self
,
client
,
key
,
version
=
None
):
@
get_client
()
def
has_key
(
self
,
client
,
key
):
"""Returns True if the key is in the cache and has not expired."""
"""Returns True if the key is in the cache and has not expired."""
key
=
self
.
make_key
(
key
,
version
=
version
)
return
client
.
exists
(
key
)
return
client
.
exists
(
key
)
def
has_key
(
self
,
key
,
version
=
None
):
@
get_client
()
raise
NotImplementedError
def
ttl
(
self
,
client
,
key
):
"""Returns the 'time-to-live' of a key. If the key is not volitile,
def
_ttl
(
self
,
client
,
key
):
i.e. it has not set expiration, then the value returned is None.
"""
Otherwise, the value is the number of seconds remaining. If the key
Returns the 'time-to-live' of a key. If the key is not volitile, i.e.
does not exist, 0 is returned.
it has not set expiration, then the value returned is None. Otherwise,
the value is the number of seconds remaining. If the key does not exist,
0 is returned.
"""
"""
if
client
.
exists
(
key
):
if
client
.
exists
(
key
):
return
client
.
ttl
(
key
)
return
client
.
ttl
(
key
)
return
0
return
0
def
ttl
(
self
,
key
,
version
=
None
):
raise
NotImplementedError
def
_delete_pattern
(
self
,
client
,
pattern
):
def
_delete_pattern
(
self
,
client
,
pattern
):
keys
=
client
.
keys
(
pattern
)
keys
=
client
.
keys
(
pattern
)
if
len
(
keys
):
if
len
(
keys
):
...
@@ -369,26 +378,24 @@ class BaseRedisCache(BaseCache):
...
@@ -369,26 +378,24 @@ class BaseRedisCache(BaseCache):
def
delete_pattern
(
self
,
pattern
,
version
=
None
):
def
delete_pattern
(
self
,
pattern
,
version
=
None
):
raise
NotImplementedError
raise
NotImplementedError
def
_get_or_set
(
self
,
client
,
key
,
func
,
timeout
=
None
):
@
get_client
(
write
=
True
)
def
get_or_set
(
self
,
client
,
key
,
func
,
timeout
=
None
):
if
not
callable
(
func
):
if
not
callable
(
func
):
raise
Exception
(
"
func must be
a callable"
)
raise
Exception
(
"
Must pass in
a callable"
)
dogpile_lock_key
=
"_lock"
+
key
.
_versioned_key
dogpile_lock_key
=
"_lock"
+
key
.
_versioned_key
dogpile_lock
=
client
.
get
(
dogpile_lock_key
)
dogpile_lock
=
client
.
get
(
dogpile_lock_key
)
if
dogpile_lock
is
None
:
if
dogpile_lock
is
None
:
self
.
_set
(
dogpile_lock_key
,
0
,
None
,
client
)
self
.
set
(
dogpile_lock_key
,
0
,
None
)
value
=
func
()
value
=
func
()
self
.
_
_
set
(
client
,
key
,
self
.
prep_value
(
value
),
None
)
self
.
_set
(
client
,
key
,
self
.
prep_value
(
value
),
None
)
self
.
_
_
set
(
client
,
dogpile_lock_key
,
0
,
timeout
)
self
.
_set
(
client
,
dogpile_lock_key
,
0
,
timeout
)
else
:
else
:
value
=
self
.
_get
(
client
,
key
)
value
=
self
.
get
(
key
.
_original_
key
)
return
value
return
value
def
get_or_set
(
self
,
key
,
func
,
timeout
=
None
,
version
=
None
):
raise
NotImplementedError
def
_reinsert_keys
(
self
,
client
):
def
_reinsert_keys
(
self
,
client
):
keys
=
client
.
keys
(
'*'
)
keys
=
client
.
keys
(
'*'
)
for
key
in
keys
:
for
key
in
keys
:
...
@@ -404,25 +411,21 @@ class BaseRedisCache(BaseCache):
...
@@ -404,25 +411,21 @@ class BaseRedisCache(BaseCache):
"""
"""
raise
NotImplementedError
raise
NotImplementedError
def
_persist
(
self
,
client
,
key
,
version
=
None
):
@
get_client
(
write
=
True
)
if
client
.
exists
(
key
):
def
persist
(
self
,
client
,
key
):
client
.
persist
(
key
)
"""Remove the timeout on a key.
def
persist
(
self
,
key
):
Equivalent to setting a timeout of None in a set command.
"""
Remove the timeout on a key. Equivalent to setting a timeout
of None in a set command.
"""
raise
NotImplementedError
def
_expire
(
self
,
client
,
key
,
timeout
,
version
=
None
):
Returns True if successful and False if not.
if
client
.
exists
(
key
):
"""
client
.
expire
(
key
,
timeout
)
return
client
.
persist
(
key
)
def
expire
(
self
,
key
,
timeout
):
@
get_client
(
write
=
True
)
def
expire
(
self
,
client
,
key
,
timeout
):
"""
"""
Set the expire time on a key
Set the expire time on a key
Will raise an exception if the key does not exist
returns True if successful and False if not.
"""
"""
r
aise
NotImplementedError
r
eturn
client
.
expire
(
key
,
timeout
)
redis_cache/backends/multiple.py
View file @
f88925a1
...
@@ -11,98 +11,38 @@ class ShardedRedisCache(BaseRedisCache):
...
@@ -11,98 +11,38 @@ class ShardedRedisCache(BaseRedisCache):
def
__init__
(
self
,
server
,
params
):
def
__init__
(
self
,
server
,
params
):
super
(
ShardedRedisCache
,
self
)
.
__init__
(
server
,
params
)
super
(
ShardedRedisCache
,
self
)
.
__init__
(
server
,
params
)
self
.
_params
=
params
self
.
_server
=
server
self
.
_pickle_version
=
None
self
.
__master_client
=
None
self
.
clients
=
{}
self
.
sharder
=
HashRing
()
self
.
sharder
=
HashRing
()
if
not
isinstance
(
server
,
(
list
,
tuple
)):
for
server
in
self
.
servers
:
servers
=
[
server
]
else
:
servers
=
server
for
server
in
servers
:
client
=
self
.
create_client
(
server
)
client
=
self
.
create_client
(
server
)
self
.
clients
[
client
.
connection_pool
.
connection_identifier
]
=
client
self
.
clients
[
client
.
connection_pool
.
connection_identifier
]
=
client
self
.
sharder
.
add
(
client
.
connection_pool
.
connection_identifier
)
self
.
sharder
.
add
(
client
.
connection_pool
.
connection_identifier
)
@
property
self
.
client_list
=
self
.
clients
.
values
()
def
master_client
(
self
):
"""
Get the write server:port of the master cache
def
get_client
(
self
,
key
,
write
=
False
):
"""
if
not
hasattr
(
self
,
'_master_client'
)
and
self
.
__master_client
is
None
:
cache
=
self
.
options
.
get
(
'MASTER_CACHE'
,
None
)
if
cache
is
None
:
self
.
_master_client
=
None
else
:
self
.
_master_client
=
self
.
create_client
(
cache
)
return
self
.
_master_client
def
get_client
(
self
,
key
,
for_write
=
False
):
if
for_write
and
self
.
master_client
is
not
None
:
return
self
.
master_client
node
=
self
.
sharder
.
get_node
(
unicode
(
key
))
node
=
self
.
sharder
.
get_node
(
unicode
(
key
))
return
self
.
clients
[
node
]
return
self
.
clients
[
node
]
def
shard
(
self
,
keys
,
for_
write
=
False
,
version
=
None
):
def
shard
(
self
,
keys
,
write
=
False
,
version
=
None
):
"""
"""
Returns a dict of keys that belong to a cache's keyspace.
Returns a dict of keys that belong to a cache's keyspace.
"""
"""
clients
=
defaultdict
(
list
)
clients
=
defaultdict
(
list
)
for
key
in
keys
:
for
key
in
keys
:
clients
[
self
.
get_client
(
key
,
for_
write
)]
.
append
(
self
.
make_key
(
key
,
version
))
clients
[
self
.
get_client
(
key
,
write
)]
.
append
(
self
.
make_key
(
key
,
version
))
return
clients
return
clients
####################
####################
# Django cache api #
# Django cache api #
####################
####################
def
add
(
self
,
key
,
value
,
timeout
=
None
,
version
=
None
):
"""
Add a value to the cache, failing if the key already exists.
Returns ``True`` if the object was added, ``False`` if not.
"""
client
=
self
.
get_client
(
key
)
key
=
self
.
make_key
(
key
,
version
=
version
)
return
self
.
_add
(
client
,
key
,
value
,
timeout
)
def
get
(
self
,
key
,
default
=
None
,
version
=
None
):
"""
Retrieve a value from the cache.
Returns unpickled value if key is found, the default if not.
"""
client
=
self
.
get_client
(
key
)
key
=
self
.
make_key
(
key
,
version
=
version
)
return
self
.
_get
(
client
,
key
,
default
)
def
set
(
self
,
key
,
value
,
timeout
=
None
,
version
=
None
,
client
=
None
):
"""
Persist a value to the cache, and set an optional expiration time.
"""
if
client
is
None
:
client
=
self
.
get_client
(
key
,
for_write
=
True
)
key
=
self
.
make_key
(
key
,
version
=
version
)
return
self
.
_set
(
key
,
value
,
timeout
,
client
=
client
)
def
delete
(
self
,
key
,
version
=
None
):
"""
Remove a key from the cache.
"""
client
=
self
.
get_client
(
key
,
for_write
=
True
)
key
=
self
.
make_key
(
key
,
version
=
version
)
return
self
.
_delete
(
client
,
key
)
def
delete_many
(
self
,
keys
,
version
=
None
):
def
delete_many
(
self
,
keys
,
version
=
None
):
"""
"""
Remove multiple keys at once.
Remove multiple keys at once.
"""
"""
clients
=
self
.
shard
(
keys
,
for_
write
=
True
,
version
=
version
)
clients
=
self
.
shard
(
keys
,
write
=
True
,
version
=
version
)
for
client
,
keys
in
clients
.
items
():
for
client
,
keys
in
clients
.
items
():
self
.
_delete_many
(
client
,
keys
)
self
.
_delete_many
(
client
,
keys
)
...
@@ -114,11 +54,8 @@ class ShardedRedisCache(BaseRedisCache):
...
@@ -114,11 +54,8 @@ class ShardedRedisCache(BaseRedisCache):
namespace will be deleted. Otherwise, all keys will be deleted.
namespace will be deleted. Otherwise, all keys will be deleted.
"""
"""
if
version
is
None
:
if
version
is
None
:
if
self
.
master_client
is
None
:
for
client
in
self
.
clients
.
itervalues
():
for
client
in
self
.
clients
.
itervalues
():
self
.
_clear
(
client
)
self
.
_clear
(
client
)
else
:
self
.
_clear
(
self
.
master_client
)
else
:
else
:
self
.
delete_pattern
(
'*'
,
version
=
version
)
self
.
delete_pattern
(
'*'
,
version
=
version
)
...
@@ -138,31 +75,23 @@ class ShardedRedisCache(BaseRedisCache):
...
@@ -138,31 +75,23 @@ class ShardedRedisCache(BaseRedisCache):
If timeout is given, that timeout will be used for the key; otherwise
If timeout is given, that timeout will be used for the key; otherwise
the default cache timeout will be used.
the default cache timeout will be used.
"""
"""
clients
=
self
.
shard
(
data
.
keys
(),
for_
write
=
True
,
version
=
version
)
clients
=
self
.
shard
(
data
.
keys
(),
write
=
True
,
version
=
version
)
if
timeout
is
None
:
if
timeout
is
None
:
for
client
,
keys
in
clients
.
items
():
for
client
,
keys
in
clients
.
items
():
subset
=
{}
subset
=
{}
for
key
in
keys
:
for
key
in
keys
:
subset
[
key
]
=
data
[
key
.
_original_key
]
subset
[
key
]
=
self
.
prep_value
(
data
[
key
.
_original_key
])
self
.
_set_many
(
client
,
subset
)
self
.
_set_many
(
client
,
subset
)
return
return
for
client
,
keys
in
clients
.
items
():
for
client
,
keys
in
clients
.
items
():
pipeline
=
client
.
pipeline
()
pipeline
=
client
.
pipeline
()
for
key
in
keys
:
for
key
in
keys
:
self
.
_set
(
key
,
data
[
key
.
_original_key
],
timeout
,
client
=
pipeline
)
value
=
self
.
prep_value
(
data
[
key
.
_original_key
])
self
.
_set
(
pipeline
,
key
,
value
,
timeout
)
pipeline
.
execute
()
pipeline
.
execute
()
def
incr
(
self
,
key
,
delta
=
1
,
version
=
None
):
"""
Add delta to value in the cache. If the key does not exist, raise a
ValueError exception.
"""
client
=
self
.
get_client
(
key
,
for_write
=
True
)
key
=
self
.
make_key
(
key
,
version
=
version
)
return
self
.
_incr
(
client
,
key
,
delta
=
delta
)
def
incr_version
(
self
,
key
,
delta
=
1
,
version
=
None
):
def
incr_version
(
self
,
key
,
delta
=
1
,
version
=
None
):
"""
"""
Adds delta to the cache version for the supplied key. Returns the
Adds delta to the cache version for the supplied key. Returns the
...
@@ -172,7 +101,7 @@ class ShardedRedisCache(BaseRedisCache):
...
@@ -172,7 +101,7 @@ class ShardedRedisCache(BaseRedisCache):
if
version
is
None
:
if
version
is
None
:
version
=
self
.
version
version
=
self
.
version
client
=
self
.
get_client
(
key
,
for_
write
=
True
)
client
=
self
.
get_client
(
key
,
write
=
True
)
old
=
self
.
make_key
(
key
,
version
=
version
)
old
=
self
.
make_key
(
key
,
version
=
version
)
new
=
self
.
make_key
(
key
,
version
=
version
+
delta
)
new
=
self
.
make_key
(
key
,
version
=
version
+
delta
)
...
@@ -182,27 +111,10 @@ class ShardedRedisCache(BaseRedisCache):
...
@@ -182,27 +111,10 @@ class ShardedRedisCache(BaseRedisCache):
# Extra api methods #
# Extra api methods #
#####################
#####################
def
has_key
(
self
,
key
,
version
=
None
):
client
=
self
.
get_client
(
key
,
for_write
=
False
)
return
self
.
_has_key
(
client
,
key
,
version
)
def
ttl
(
self
,
key
,
version
=
None
):
client
=
self
.
get_client
(
key
,
for_write
=
False
)
key
=
self
.
make_key
(
key
,
version
=
version
)
return
self
.
_ttl
(
client
,
key
)
def
delete_pattern
(
self
,
pattern
,
version
=
None
):
def
delete_pattern
(
self
,
pattern
,
version
=
None
):
pattern
=
self
.
make_key
(
pattern
,
version
=
version
)
pattern
=
self
.
make_key
(
pattern
,
version
=
version
)
if
self
.
master_client
is
None
:
for
client
in
self
.
clients
.
itervalues
():
for
client
in
self
.
clients
.
itervalues
():
self
.
_delete_pattern
(
client
,
pattern
)
self
.
_delete_pattern
(
client
,
pattern
)
else
:
self
.
_delete_pattern
(
self
.
master_client
,
pattern
)
def
get_or_set
(
self
,
key
,
func
,
timeout
=
None
,
version
=
None
):
client
=
self
.
get_client
(
key
,
for_write
=
True
)
key
=
self
.
make_key
(
key
,
version
=
version
)
return
self
.
_get_or_set
(
client
,
key
,
func
,
timeout
)
def
reinsert_keys
(
self
):
def
reinsert_keys
(
self
):
"""
"""
...
@@ -210,14 +122,3 @@ class ShardedRedisCache(BaseRedisCache):
...
@@ -210,14 +122,3 @@ class ShardedRedisCache(BaseRedisCache):
"""
"""
for
client
in
self
.
clients
.
itervalues
():
for
client
in
self
.
clients
.
itervalues
():
self
.
_reinsert_keys
(
client
)
self
.
_reinsert_keys
(
client
)
print
def
persist
(
self
,
key
,
version
=
None
):
client
=
self
.
get_client
(
key
,
for_write
=
True
)
key
=
self
.
make_key
(
key
,
version
=
version
)
self
.
_persist
(
client
,
key
,
version
)
def
expire
(
self
,
key
,
timeout
,
version
=
None
):
client
=
self
.
get_client
(
key
,
for_write
=
True
)
key
=
self
.
make_key
(
key
,
version
=
version
)
self
.
_expire
(
client
,
key
,
timeout
,
version
)
redis_cache/backends/single.py
View file @
f88925a1
...
@@ -2,6 +2,7 @@ try:
...
@@ -2,6 +2,7 @@ try:
import
cPickle
as
pickle
import
cPickle
as
pickle
except
ImportError
:
except
ImportError
:
import
pickle
import
pickle
import
random
from
redis_cache.backends.base
import
BaseRedisCache
from
redis_cache.backends.base
import
BaseRedisCache
from
redis_cache.compat
import
bytes_type
,
DEFAULT_TIMEOUT
from
redis_cache.compat
import
bytes_type
,
DEFAULT_TIMEOUT
...
@@ -15,75 +16,41 @@ class RedisCache(BaseRedisCache):
...
@@ -15,75 +16,41 @@ class RedisCache(BaseRedisCache):
"""
"""
super
(
RedisCache
,
self
)
.
__init__
(
server
,
params
)
super
(
RedisCache
,
self
)
.
__init__
(
server
,
params
)
if
not
isinstance
(
server
,
bytes_type
):
for
server
in
self
.
servers
:
self
.
_server
,
=
server
client
=
self
.
create_client
(
server
)
self
.
clients
[
client
.
connection_pool
.
connection_identifier
]
=
client
self
.
client
=
self
.
create_client
(
server
)
self
.
client_list
=
self
.
clients
.
values
()
self
.
clients
=
{
self
.
master_client
=
self
.
get_master_client
()
self
.
client
.
connection_pool
.
connection_identifier
:
self
.
client
}
def
get_client
(
self
,
*
args
):
def
get_client
(
self
,
key
,
write
=
False
):
return
self
.
client
if
write
and
self
.
master_client
is
not
None
:
return
self
.
master_client
return
random
.
choice
(
self
.
client_list
)
####################
####################
# Django cache api #
# Django cache api #
####################
####################
def
add
(
self
,
key
,
value
,
timeout
=
None
,
version
=
None
):
"""
Add a value to the cache, failing if the key already exists.
Returns ``True`` if the object was added, ``False`` if not.
"""
key
=
self
.
make_key
(
key
,
version
=
version
)
return
self
.
_add
(
self
.
client
,
key
,
value
,
timeout
)
def
get
(
self
,
key
,
default
=
None
,
version
=
None
):
"""
Retrieve a value from the cache.
Returns unpickled value if key is found, the default if not.
"""
key
=
self
.
make_key
(
key
,
version
=
version
)
return
self
.
_get
(
self
.
client
,
key
,
default
)
def
set
(
self
,
key
,
value
,
timeout
=
DEFAULT_TIMEOUT
,
version
=
None
,
client
=
None
):
"""
Persist a value to the cache, and set an optional expiration time.
"""
key
=
self
.
make_key
(
key
,
version
=
version
)
return
self
.
_set
(
key
,
value
,
timeout
,
client
=
self
.
client
)
def
delete
(
self
,
key
,
version
=
None
):
"""
Remove a key from the cache.
"""
key
=
self
.
make_key
(
key
,
version
=
version
)
return
self
.
_delete
(
self
.
client
,
key
)
def
delete_many
(
self
,
keys
,
version
=
None
):
def
delete_many
(
self
,
keys
,
version
=
None
):
"""
"""Remove multiple keys at once."""
Remove multiple keys at once.
"""
versioned_keys
=
self
.
make_keys
(
keys
,
version
=
version
)
versioned_keys
=
self
.
make_keys
(
keys
,
version
=
version
)
self
.
_delete_many
(
self
.
client
,
versioned_keys
)
self
.
_delete_many
(
self
.
master_
client
,
versioned_keys
)
def
clear
(
self
,
version
=
None
):
def
clear
(
self
,
version
=
None
):
"""
"""Flush cache keys.
Flush cache keys.
If version is specified, all keys belonging the version's key
If version is specified, all keys belonging the version's key
namespace will be deleted. Otherwise, all keys will be deleted.
namespace will be deleted. Otherwise, all keys will be deleted.
"""
"""
if
version
is
None
:
if
version
is
None
:
self
.
_clear
(
self
.
client
)
self
.
_clear
(
self
.
master_
client
)
else
:
else
:
self
.
delete_pattern
(
'*'
,
version
=
version
)
self
.
delete_pattern
(
'*'
,
version
=
version
)
def
get_many
(
self
,
keys
,
version
=
None
):
def
get_many
(
self
,
keys
,
version
=
None
):
versioned_keys
=
self
.
make_keys
(
keys
,
version
=
version
)
versioned_keys
=
self
.
make_keys
(
keys
,
version
=
version
)
return
self
.
_get_many
(
self
.
client
,
keys
,
versioned_keys
=
versioned_keys
)
return
self
.
_get_many
(
self
.
master_
client
,
keys
,
versioned_keys
=
versioned_keys
)
def
set_many
(
self
,
data
,
timeout
=
None
,
version
=
None
):
def
set_many
(
self
,
data
,
timeout
=
None
,
version
=
None
):
"""
"""
...
@@ -97,22 +64,15 @@ class RedisCache(BaseRedisCache):
...
@@ -97,22 +64,15 @@ class RedisCache(BaseRedisCache):
if
timeout
is
None
:
if
timeout
is
None
:
new_data
=
{}
new_data
=
{}
for
key
in
versioned_keys
:
for
key
in
versioned_keys
:
new_data
[
key
]
=
data
[
key
.
_original_key
]
new_data
[
key
]
=
self
.
prep_value
(
data
[
key
.
_original_key
])
return
self
.
_set_many
(
self
.
client
,
new_data
)
return
self
.
_set_many
(
self
.
master_
client
,
new_data
)
pipeline
=
self
.
client
.
pipeline
()
pipeline
=
self
.
master_
client
.
pipeline
()
for
key
in
versioned_keys
:
for
key
in
versioned_keys
:
self
.
_set
(
key
,
data
[
key
.
_original_key
],
timeout
,
client
=
pipeline
)
value
=
self
.
prep_value
(
data
[
key
.
_original_key
])
self
.
_set
(
pipeline
,
key
,
value
,
timeout
)
pipeline
.
execute
()
pipeline
.
execute
()
def
incr
(
self
,
key
,
delta
=
1
,
version
=
None
):
"""
Add delta to value in the cache. If the key does not exist, raise a
ValueError exception.
"""
key
=
self
.
make_key
(
key
,
version
=
version
)
return
self
.
_incr
(
self
.
client
,
key
,
delta
=
delta
)
def
incr_version
(
self
,
key
,
delta
=
1
,
version
=
None
):
def
incr_version
(
self
,
key
,
delta
=
1
,
version
=
None
):
"""
"""
Adds delta to the cache version for the supplied key. Returns the
Adds delta to the cache version for the supplied key. Returns the
...
@@ -125,37 +85,18 @@ class RedisCache(BaseRedisCache):
...
@@ -125,37 +85,18 @@ class RedisCache(BaseRedisCache):
old
=
self
.
make_key
(
key
,
version
)
old
=
self
.
make_key
(
key
,
version
)
new
=
self
.
make_key
(
key
,
version
=
version
+
delta
)
new
=
self
.
make_key
(
key
,
version
=
version
+
delta
)
return
self
.
_incr_version
(
self
.
client
,
old
,
new
,
delta
,
version
)
return
self
.
_incr_version
(
self
.
master_
client
,
old
,
new
,
delta
,
version
)
#####################
#####################
# Extra api methods #
# Extra api methods #
#####################
#####################
def
has_key
(
self
,
key
,
version
=
None
):
return
self
.
_has_key
(
self
.
client
,
key
,
version
)
def
ttl
(
self
,
key
,
version
=
None
):
key
=
self
.
make_key
(
key
,
version
=
version
)
return
self
.
_ttl
(
self
.
client
,
key
)
def
delete_pattern
(
self
,
pattern
,
version
=
None
):
def
delete_pattern
(
self
,
pattern
,
version
=
None
):
pattern
=
self
.
make_key
(
pattern
,
version
=
version
)
pattern
=
self
.
make_key
(
pattern
,
version
=
version
)
self
.
_delete_pattern
(
self
.
client
,
pattern
)
self
.
_delete_pattern
(
self
.
master_client
,
pattern
)
def
get_or_set
(
self
,
key
,
func
,
timeout
=
None
,
version
=
None
):
key
=
self
.
make_key
(
key
,
version
=
version
)
return
self
.
_get_or_set
(
self
.
client
,
key
,
func
,
timeout
)
def
reinsert_keys
(
self
):
def
reinsert_keys
(
self
):
"""
"""
Reinsert cache entries using the current pickle protocol version.
Reinsert cache entries using the current pickle protocol version.
"""
"""
self
.
_reinsert_keys
(
self
.
client
)
self
.
_reinsert_keys
(
self
.
master_client
)
def
persist
(
self
,
key
,
version
=
None
):
key
=
self
.
make_key
(
key
,
version
=
version
)
self
.
_persist
(
self
.
client
,
key
,
version
)
def
expire
(
self
,
key
,
timeout
,
version
=
None
):
key
=
self
.
make_key
(
key
,
version
=
version
)
self
.
_expire
(
self
.
client
,
key
,
timeout
,
version
)
tests/testapp/tests/master_slave_tests.py
View file @
f88925a1
...
@@ -21,7 +21,7 @@ LOCATIONS = [
...
@@ -21,7 +21,7 @@ LOCATIONS = [
@
override_settings
(
CACHES
=
{
@
override_settings
(
CACHES
=
{
'default'
:
{
'default'
:
{
'BACKEND'
:
'redis_cache.
Sharded
RedisCache'
,
'BACKEND'
:
'redis_cache.RedisCache'
,
'LOCATION'
:
LOCATIONS
,
'LOCATION'
:
LOCATIONS
,
'OPTIONS'
:
{
'OPTIONS'
:
{
'DB'
:
1
,
'DB'
:
1
,
...
...
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