diff --git a/README.rst b/README.rst index ccf323b1..8d597df7 100644 --- a/README.rst +++ b/README.rst @@ -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 diff --git a/django_redis/pool.py b/django_redis/pool.py index 44afa943..c5704076 100644 --- a/django_redis/pool.py +++ b/django_redis/pool.py @@ -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 {}) diff --git a/setup.cfg b/setup.cfg index 9395f819..78032a20 100644 --- a/setup.cfg +++ b/setup.cfg @@ -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} diff --git a/tests/settings/sqlite_sentinel_opts.py b/tests/settings/sqlite_sentinel_opts.py new file mode 100644 index 00000000..29f079ed --- /dev/null +++ b/tests/settings/sqlite_sentinel_opts.py @@ -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 diff --git a/tests/test_connection_string.py b/tests/test_connection_string.py index 81dffebe..520e28cd 100644 --- a/tests/test_connection_string.py +++ b/tests/test_connection_string.py @@ -17,3 +17,24 @@ def test_connection_strings(connection_string: str): ) res = cf.make_connection_params(connection_string) assert res["url"] == connection_string + + +@pytest.mark.parametrize( + "connection_string", + [ + "unix://tmp/foo.bar?db=1", + "redis://localhost/2", + "rediss://localhost:3333?db=2", + ], +) +def test_connection_strings_with_conn_factory_in_opts(connection_string: str): + sentinel_conn_factory = "django_redis.pool.SentinelConnectionFactory" + cf = pool.get_connection_factory( + path=None, + options={ + "CONNECTION_FACTORY": sentinel_conn_factory, + "SENTINELS": [("127.0.0.1", "26739")], + }, + ) + res = cf.make_connection_params(connection_string) + assert res["url"] == connection_string