Skip to content

Commit a582fe4

Browse files
authored
Merge pull request #680 from RealFatCat/feat/connection-factory-in-cache-options
Connection factory goes to cache options
2 parents 097c997 + 77097d3 commit a582fe4

File tree

6 files changed

+143
-0
lines changed

6 files changed

+143
-0
lines changed

README.rst

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,35 @@ In order to enable this functionality you should add the following:
736736
},
737737
}
738738
739+
It is also possible to set some caches as sentinels and some as not:
740+
741+
.. code-block:: python
742+
743+
SENTINELS = [
744+
('sentinel-1', 26379),
745+
('sentinel-2', 26379),
746+
('sentinel-3', 26379),
747+
]
748+
CACHES = {
749+
"sentinel": {
750+
"BACKEND": "django_redis.cache.RedisCache",
751+
"LOCATION": "redis://service_name/db",
752+
"OPTIONS": {
753+
"CLIENT_CLASS": "django_redis.client.SentinelClient",
754+
"SENTINELS": SENTINELS,
755+
"CONNECTION_POOL_CLASS": "redis.sentinel.SentinelConnectionPool",
756+
"CONNECTION_FACTORY": "django_redis.pool.SentinelConnectionFactory",
757+
},
758+
},
759+
"default": {
760+
"BACKEND": "django_redis.cache.RedisCache",
761+
"LOCATION": "redis://127.0.0.1:6379/1",
762+
"OPTIONS": {
763+
"CLIENT_CLASS": "django_redis.client.DefaultClient",
764+
},
765+
},
766+
}
767+
739768
.. _Redis Sentinels: https://redis.io/topics/sentinel
740769

741770
Pluggable parsers

changelog.d/680.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Connection factory goes to cache options

django_redis/pool.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,9 @@ def get_connection_factory(path=None, options=None):
184184
"DJANGO_REDIS_CONNECTION_FACTORY",
185185
"django_redis.pool.ConnectionFactory",
186186
)
187+
opt_conn_factory = options.get("CONNECTION_FACTORY")
188+
if opt_conn_factory:
189+
path = opt_conn_factory
187190

188191
cls = import_string(path)
189192
return cls(options or {})

setup.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ commands =
107107
{envpython} -m pytest --cov-append --cov-report= --ds=settings.sqlite_lz4 {posargs}
108108
{envpython} -m pytest --cov-append --cov-report= --ds=settings.sqlite_msgpack {posargs}
109109
{envpython} -m pytest --cov-append --cov-report= --ds=settings.sqlite_sentinel {posargs}
110+
{envpython} -m pytest --cov-append --cov-report= --ds=settings.sqlite_sentinel_opts {posargs}
110111
{envpython} -m pytest --cov-append --cov-report= --ds=settings.sqlite_sharding {posargs}
111112
{envpython} -m pytest --cov-append --cov-report= --ds=settings.sqlite_usock {posargs}
112113
{envpython} -m pytest --cov-append --cov-report= --ds=settings.sqlite_zlib {posargs}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
SECRET_KEY = "django_tests_secret_key"
2+
3+
SENTINELS = [("127.0.0.1", 26379)]
4+
5+
conn_factory = "django_redis.pool.SentinelConnectionFactory"
6+
7+
CACHES = {
8+
"default": {
9+
"BACKEND": "django_redis.cache.RedisCache",
10+
"LOCATION": ["redis://default_service?db=5"],
11+
"OPTIONS": {
12+
"CLIENT_CLASS": "django_redis.client.DefaultClient",
13+
"SENTINELS": SENTINELS,
14+
"CONNECTION_FACTORY": conn_factory,
15+
},
16+
},
17+
"doesnotexist": {
18+
"BACKEND": "django_redis.cache.RedisCache",
19+
"LOCATION": "redis://missing_service?db=1",
20+
"OPTIONS": {
21+
"CLIENT_CLASS": "django_redis.client.DefaultClient",
22+
"SENTINELS": SENTINELS,
23+
"CONNECTION_FACTORY": conn_factory,
24+
},
25+
},
26+
"sample": {
27+
"BACKEND": "django_redis.cache.RedisCache",
28+
"LOCATION": "redis://default_service?db=1",
29+
"OPTIONS": {
30+
"CLIENT_CLASS": "django_redis.client.SentinelClient",
31+
"SENTINELS": SENTINELS,
32+
"CONNECTION_FACTORY": conn_factory,
33+
},
34+
},
35+
"with_prefix": {
36+
"BACKEND": "django_redis.cache.RedisCache",
37+
"LOCATION": "redis://default_service?db=1",
38+
"KEY_PREFIX": "test-prefix",
39+
"OPTIONS": {
40+
"CLIENT_CLASS": "django_redis.client.DefaultClient",
41+
"SENTINELS": SENTINELS,
42+
"CONNECTION_FACTORY": conn_factory,
43+
},
44+
},
45+
}
46+
47+
INSTALLED_APPS = ["django.contrib.sessions"]
48+
49+
USE_TZ = False

tests/test_connection_factory.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import pytest
2+
from django.core.exceptions import ImproperlyConfigured
3+
4+
from django_redis import pool
5+
6+
7+
def test_connection_factory_redefine_from_opts():
8+
cf = pool.get_connection_factory(
9+
path="django_redis.pool.ConnectionFactory",
10+
options={
11+
"CONNECTION_FACTORY": "django_redis.pool.SentinelConnectionFactory",
12+
"SENTINELS": [("127.0.0.1", "26739")],
13+
},
14+
)
15+
assert cf.__class__.__name__ == "SentinelConnectionFactory"
16+
17+
18+
@pytest.mark.parametrize(
19+
"conn_factory,expected",
20+
[
21+
("django_redis.pool.SentinelConnectionFactory", pool.SentinelConnectionFactory),
22+
("django_redis.pool.ConnectionFactory", pool.ConnectionFactory),
23+
],
24+
)
25+
def test_connection_factory_opts(conn_factory: str, expected):
26+
cf = pool.get_connection_factory(
27+
path=None,
28+
options={
29+
"CONNECTION_FACTORY": conn_factory,
30+
"SENTINELS": [("127.0.0.1", "26739")],
31+
},
32+
)
33+
assert isinstance(cf, expected)
34+
35+
36+
@pytest.mark.parametrize(
37+
"conn_factory,expected",
38+
[
39+
("django_redis.pool.SentinelConnectionFactory", pool.SentinelConnectionFactory),
40+
("django_redis.pool.ConnectionFactory", pool.ConnectionFactory),
41+
],
42+
)
43+
def test_connection_factory_path(conn_factory: str, expected):
44+
cf = pool.get_connection_factory(
45+
path=conn_factory,
46+
options={
47+
"SENTINELS": [("127.0.0.1", "26739")],
48+
},
49+
)
50+
assert isinstance(cf, expected)
51+
52+
53+
def test_connection_factory_no_sentinels():
54+
with pytest.raises(ImproperlyConfigured):
55+
pool.get_connection_factory(
56+
path=None,
57+
options={
58+
"CONNECTION_FACTORY": "django_redis.pool.SentinelConnectionFactory",
59+
},
60+
)

0 commit comments

Comments
 (0)