Просмотр исходного кода

fix: Lazily create redis client for rate limiter (#62942)

There seems to be some import order issue where the settings aren't
properly initialized when initializing the redis cluster during start
up. Initialize the redis cluster lazily to ensure the settings are
properly initialized.

Fixes SENTRY-2DG8
Tony Xiao 1 год назад
Родитель
Сommit
745b543af6
1 измененных файлов с 18 добавлено и 5 удалено
  1. 18 5
      src/sentry/ratelimits/sliding_windows.py

+ 18 - 5
src/sentry/ratelimits/sliding_windows.py

@@ -1,3 +1,5 @@
+from __future__ import annotations
+
 from typing import Any, Optional, Sequence, Tuple
 from typing import Any, Optional, Sequence, Tuple
 
 
 from sentry_redis_tools.clients import RedisCluster, StrictRedis
 from sentry_redis_tools.clients import RedisCluster, StrictRedis
@@ -118,13 +120,24 @@ class SlidingWindowRateLimiter(Service):
 
 
 class RedisSlidingWindowRateLimiter(SlidingWindowRateLimiter):
 class RedisSlidingWindowRateLimiter(SlidingWindowRateLimiter):
     def __init__(self, **options: Any) -> None:
     def __init__(self, **options: Any) -> None:
-        cluster_key = options.get("cluster", "default")
-        client = redis.redis_clusters.get(cluster_key)
-        assert isinstance(client, (StrictRedis, RedisCluster)), client
-        self.client = client
-        self.impl = RedisSlidingWindowRateLimiterImpl(self.client)
+        self.cluster_key = options.get("cluster", "default")
+        self._client: RedisCluster | StrictRedis | None = None
+        self._impl: RedisSlidingWindowRateLimiterImpl | None = None
         super().__init__(**options)
         super().__init__(**options)
 
 
+    @property
+    def client(self) -> StrictRedis | RedisCluster:
+        if self._client is None:
+            self._client = redis.redis_clusters.get(self.cluster_key)
+            assert isinstance(self._client, (StrictRedis, RedisCluster)), self._client
+        return self._client
+
+    @property
+    def impl(self):
+        if self._impl is None:
+            self._impl = RedisSlidingWindowRateLimiterImpl(self.client)
+        return self._impl
+
     def validate(self) -> None:
     def validate(self) -> None:
         try:
         try:
             self.client.ping()
             self.client.ping()