From 7d8716dbce962d844a57896833984bd279f805a2 Mon Sep 17 00:00:00 2001 From: JackiLin Date: Wed, 4 Sep 2024 13:31:36 +0800 Subject: [PATCH] Fix sentinel mode read-write separation --- django_redis/pool.py | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/django_redis/pool.py b/django_redis/pool.py index b0e5f2a3..20817992 100644 --- a/django_redis/pool.py +++ b/django_redis/pool.py @@ -1,5 +1,5 @@ from typing import Dict -from urllib.parse import parse_qs, urlparse +from urllib.parse import parse_qs, urlparse,urlencode,urlunparse from django.conf import settings from django.core.exceptions import ImproperlyConfigured @@ -163,15 +163,30 @@ def get_connection_pool(self, params): # explicitly set service_name and sentinel_manager for the # SentinelConnectionPool constructor since will be called by from_url cp_params = dict(params) - cp_params.update(service_name=url.hostname, sentinel_manager=self._sentinel) - pool = super().get_connection_pool(cp_params) - # convert "is_master" to a boolean if set on the URL, otherwise if not # provided it defaults to True. - is_master = parse_qs(url.query).get("is_master") + query_params = parse_qs(url.query) + is_master = query_params.get("is_master") if is_master: - pool.is_master = to_bool(is_master[0]) + cp_params['is_master'] = to_bool(is_master[0]) + # then remove the "is_master" query string from the URL + # so it doesn't interfere with the SentinelConnectionPool constructor + if 'is_master' in query_params: + del query_params['is_master'] + new_query = urlencode(query_params, doseq=True) + + new_url = urlunparse(( + url.scheme, + url.netloc, + url.path, + url.params, + new_query, + url.fragment + )) + + cp_params.update(service_name=url.hostname, sentinel_manager=self._sentinel,url=new_url) + pool = super().get_connection_pool(cp_params) return pool