Skip to content

Commit

Permalink
Merge pull request #680 from RealFatCat/feat/connection-factory-in-ca…
Browse files Browse the repository at this point in the history
…che-options

Connection factory goes to cache options
  • Loading branch information
WisdomPill committed Sep 28, 2023
2 parents 097c997 + 77097d3 commit a582fe4
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 0 deletions.
29 changes: 29 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,35 @@ In order to enable this functionality you should add the following:
},
}
It is also possible to set some caches as sentinels and some as not:

.. code-block:: python
SENTINELS = [
('sentinel-1', 26379),
('sentinel-2', 26379),
('sentinel-3', 26379),
]
CACHES = {
"sentinel": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://service_name/db",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.SentinelClient",
"SENTINELS": SENTINELS,
"CONNECTION_POOL_CLASS": "redis.sentinel.SentinelConnectionPool",
"CONNECTION_FACTORY": "django_redis.pool.SentinelConnectionFactory",
},
},
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379/1",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
},
},
}
.. _Redis Sentinels: https://redis.io/topics/sentinel

Pluggable parsers
Expand Down
1 change: 1 addition & 0 deletions changelog.d/680.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Connection factory goes to cache options
3 changes: 3 additions & 0 deletions django_redis/pool.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,9 @@ def get_connection_factory(path=None, options=None):
"DJANGO_REDIS_CONNECTION_FACTORY",
"django_redis.pool.ConnectionFactory",
)
opt_conn_factory = options.get("CONNECTION_FACTORY")
if opt_conn_factory:
path = opt_conn_factory

cls = import_string(path)
return cls(options or {})
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ commands =
{envpython} -m pytest --cov-append --cov-report= --ds=settings.sqlite_lz4 {posargs}
{envpython} -m pytest --cov-append --cov-report= --ds=settings.sqlite_msgpack {posargs}
{envpython} -m pytest --cov-append --cov-report= --ds=settings.sqlite_sentinel {posargs}
{envpython} -m pytest --cov-append --cov-report= --ds=settings.sqlite_sentinel_opts {posargs}
{envpython} -m pytest --cov-append --cov-report= --ds=settings.sqlite_sharding {posargs}
{envpython} -m pytest --cov-append --cov-report= --ds=settings.sqlite_usock {posargs}
{envpython} -m pytest --cov-append --cov-report= --ds=settings.sqlite_zlib {posargs}
Expand Down
49 changes: 49 additions & 0 deletions tests/settings/sqlite_sentinel_opts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
SECRET_KEY = "django_tests_secret_key"

SENTINELS = [("127.0.0.1", 26379)]

conn_factory = "django_redis.pool.SentinelConnectionFactory"

CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": ["redis://default_service?db=5"],
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"SENTINELS": SENTINELS,
"CONNECTION_FACTORY": conn_factory,
},
},
"doesnotexist": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://missing_service?db=1",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"SENTINELS": SENTINELS,
"CONNECTION_FACTORY": conn_factory,
},
},
"sample": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://default_service?db=1",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.SentinelClient",
"SENTINELS": SENTINELS,
"CONNECTION_FACTORY": conn_factory,
},
},
"with_prefix": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://default_service?db=1",
"KEY_PREFIX": "test-prefix",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"SENTINELS": SENTINELS,
"CONNECTION_FACTORY": conn_factory,
},
},
}

INSTALLED_APPS = ["django.contrib.sessions"]

USE_TZ = False
60 changes: 60 additions & 0 deletions tests/test_connection_factory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import pytest
from django.core.exceptions import ImproperlyConfigured

from django_redis import pool


def test_connection_factory_redefine_from_opts():
cf = pool.get_connection_factory(
path="django_redis.pool.ConnectionFactory",
options={
"CONNECTION_FACTORY": "django_redis.pool.SentinelConnectionFactory",
"SENTINELS": [("127.0.0.1", "26739")],
},
)
assert cf.__class__.__name__ == "SentinelConnectionFactory"


@pytest.mark.parametrize(
"conn_factory,expected",
[
("django_redis.pool.SentinelConnectionFactory", pool.SentinelConnectionFactory),
("django_redis.pool.ConnectionFactory", pool.ConnectionFactory),
],
)
def test_connection_factory_opts(conn_factory: str, expected):
cf = pool.get_connection_factory(
path=None,
options={
"CONNECTION_FACTORY": conn_factory,
"SENTINELS": [("127.0.0.1", "26739")],
},
)
assert isinstance(cf, expected)


@pytest.mark.parametrize(
"conn_factory,expected",
[
("django_redis.pool.SentinelConnectionFactory", pool.SentinelConnectionFactory),
("django_redis.pool.ConnectionFactory", pool.ConnectionFactory),
],
)
def test_connection_factory_path(conn_factory: str, expected):
cf = pool.get_connection_factory(
path=conn_factory,
options={
"SENTINELS": [("127.0.0.1", "26739")],
},
)
assert isinstance(cf, expected)


def test_connection_factory_no_sentinels():
with pytest.raises(ImproperlyConfigured):
pool.get_connection_factory(
path=None,
options={
"CONNECTION_FACTORY": "django_redis.pool.SentinelConnectionFactory",
},
)

0 comments on commit a582fe4

Please sign in to comment.