Skip to content

Commit dc615c1

Browse files
committed
Add configurable connection pool for Redis-py
- Redis was using a default connection pool, but not tuned or configured - Log every ignored Redis exception - Use redis[hiredis] for dependencies, so redis-py can choose the best hiredis version
1 parent 5391e5d commit dc615c1

File tree

5 files changed

+40
-8
lines changed

5 files changed

+40
-8
lines changed

config/settings/base.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,9 @@
529529
}
530530

531531
REDIS_URL = env("REDIS_URL", default="redis://localhost:6379/0")
532+
REDIS_TIMEOUT_SECONDS = env("REDIS_TIMEOUT_SECONDS", default=5)
533+
REDIS_CONNECTION_TIMEOUT_SECONDS = env("REDIS_CONNECTION_TIMEOUT_SECONDS", default=5)
534+
REDIS_POOL_MAX_CONNECTIONS = env("REDIS_POOL_MAX_CONNECTIONS", default=300)
532535

533536
# Ethereum RPC
534537
# ------------------------------------------------------------------------------

config/settings/local.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
from .base import * # noqa
22
from .base import env
3+
from .base import (
4+
REDIS_URL,
5+
REDIS_CONNECTION_TIMEOUT_SECONDS,
6+
REDIS_TIMEOUT_SECONDS,
7+
REDIS_POOL_MAX_CONNECTIONS,
8+
)
9+
310

411
# GENERAL
512
# ------------------------------------------------------------------------------
@@ -13,8 +20,6 @@
1320
# https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts
1421
ALLOWED_HOSTS = env.list("DJANGO_ALLOWED_HOSTS", default=["*"])
1522

16-
REDIS_URL = env.str("REDIS_URL")
17-
1823
# SECURITY
1924
# ------------------------------------------------------------------------------
2025
# https://docs.djangoproject.com/en/dev/ref/middleware/#x-content-type-options-nosniff
@@ -29,6 +34,9 @@
2934
"LOCATION": REDIS_URL,
3035
"OPTIONS": {
3136
"CLIENT_CLASS": "django_redis.client.DefaultClient",
37+
"SOCKET_CONNECT_TIMEOUT": REDIS_CONNECTION_TIMEOUT_SECONDS,
38+
"SOCKET_TIMEOUT": REDIS_TIMEOUT_SECONDS,
39+
"CONNECTION_POOL_KWARGS": {"max_connections": REDIS_POOL_MAX_CONNECTIONS},
3240
# Mimicking memcache behavior.
3341
# http://niwinz.github.io/django-redis/latest/#_memcached_exceptions_behavior
3442
"IGNORE_EXCEPTIONS": True,
@@ -40,6 +48,9 @@
4048
},
4149
}
4250

51+
# Log redis exceptions ignored
52+
DJANGO_REDIS_LOG_IGNORED_EXCEPTIONS = True
53+
4354
# django-debug-toolbar
4455
# ------------------------------------------------------------------------------
4556
# https://django-debug-toolbar.readthedocs.io/en/latest/installation.html#prerequisites

config/settings/production.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
from .base import * # noqa
22
from .base import env
3+
from .base import (
4+
REDIS_URL,
5+
REDIS_CONNECTION_TIMEOUT_SECONDS,
6+
REDIS_TIMEOUT_SECONDS,
7+
REDIS_POOL_MAX_CONNECTIONS,
8+
)
39

410
# GENERAL
511
# ------------------------------------------------------------------------------
@@ -13,16 +19,18 @@
1319
# DATABASES['default'] = env.db('DATABASE_URL') # noqa F405
1420
DATABASES["default"]["ATOMIC_REQUESTS"] = False # noqa F405
1521

16-
REDIS_URL = env.str("REDIS_URL")
17-
1822
# CACHES
1923
# ------------------------------------------------------------------------------
24+
# https://docs.djangoproject.com/en/dev/ref/settings/#caches
2025
CACHES = {
2126
"default": {
2227
"BACKEND": "django_redis.cache.RedisCache",
2328
"LOCATION": REDIS_URL,
2429
"OPTIONS": {
2530
"CLIENT_CLASS": "django_redis.client.DefaultClient",
31+
"SOCKET_CONNECT_TIMEOUT": REDIS_CONNECTION_TIMEOUT_SECONDS,
32+
"SOCKET_TIMEOUT": REDIS_TIMEOUT_SECONDS,
33+
"CONNECTION_POOL_KWARGS": {"max_connections": REDIS_POOL_MAX_CONNECTIONS},
2634
# Mimicking memcache behavior.
2735
# http://niwinz.github.io/django-redis/latest/#_memcached_exceptions_behavior
2836
"IGNORE_EXCEPTIONS": True,
@@ -34,6 +42,9 @@
3442
},
3543
}
3644

45+
# Log redis exceptions ignored
46+
DJANGO_REDIS_LOG_IGNORED_EXCEPTIONS = True
47+
3748
# SECURITY
3849
# ------------------------------------------------------------------------------
3950
# https://docs.djangoproject.com/en/dev/ref/middleware/#x-content-type-options-nosniff

requirements.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,11 @@ docutils==0.22.2
2121
drf-spectacular==0.28.0
2222
flower==2.0.1
2323
gunicorn[gevent]==23.0.0
24-
hiredis==3.2.1
2524
packaging>=21.0
2625
pika==1.3.2
2726
pillow==11.3.0
2827
psycopg[binary,pool]==3.2.12
29-
redis==6.4.0
28+
redis[hiredis]==6.4.0
3029
requests==2.32.5
3130
safe-eth-py[django]==7.14.0
3231
web3==7.14.0

safe_transaction_service/utils/redis.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from django.conf import settings
66

7-
from redis import Redis
7+
from redis import ConnectionPool, Redis
88

99
logger = logging.getLogger(__name__)
1010

@@ -16,4 +16,12 @@ def get_redis() -> Redis:
1616
# Encode memoryview for redis when using pickle
1717
copyreg.pickle(memoryview, lambda val: (memoryview, (bytes(val),)))
1818

19-
return Redis.from_url(settings.REDIS_URL)
19+
connection_pool = ConnectionPool(
20+
max_connections=settings.REDIS_POOL_MAX_CONNECTIONS
21+
).from_url(
22+
settings.REDIS_URL,
23+
socket_connect_timeout=settings.REDIS_CONNECTION_TIMEOUT_SECONDS,
24+
socket_timeout=settings.REDIS_TIMEOUT_SECONDS,
25+
health_check_interval=30,
26+
)
27+
return Redis(connection_pool=connection_pool)

0 commit comments

Comments
 (0)