From 809a20a8cc570bee4cf56beca7fe9ee7265a1793 Mon Sep 17 00:00:00 2001 From: Bobby Watson Date: Sat, 12 Oct 2024 20:09:13 -0400 Subject: [PATCH] [AWS Elasticache Serverless Redis] Handle redis servers that return non-string versions (#2131) * Handle redis servers that return non-string versions * Add tests for AWS elasticache redis version output --- rq/utils.py | 8 +++++++- tests/test_utils.py | 14 ++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/rq/utils.py b/rq/utils.py index 792bf1d3..a1d382cf 100644 --- a/rq/utils.py +++ b/rq/utils.py @@ -287,10 +287,16 @@ def get_version(connection: 'Redis') -> Tuple[int, int, int]: try: # Getting the connection info for each job tanks performance, we can cache it on the connection object if not getattr(connection, "__rq_redis_server_version", None): + # Cast the version string to a tuple of integers. Some Redis implementations may return a float. + version_str = str(connection.info("server")["redis_version"]) + version_parts = [int(i) for i in version_str.split('.')[:3]] + # Ensure the version tuple has exactly three elements + while len(version_parts) < 3: + version_parts.append(0) setattr( connection, "__rq_redis_server_version", - tuple(int(i) for i in str(connection.info("server")["redis_version"]).split('.')[:3]), + tuple(version_parts), ) return getattr(connection, "__rq_redis_server_version") except ResponseError: # fakeredis doesn't implement Redis' INFO command diff --git a/tests/test_utils.py b/tests/test_utils.py index fea02bf6..8b9778a9 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -112,6 +112,20 @@ class TestUtils(RQTestCase): self.assertEqual(get_version(DummyRedis()), (3, 0, 7)) + # Parses 2 digit version numbers correctly (Seen in AWS ElastiCache Redis) + class DummyRedis(Redis): + def info(*args): + return {'redis_version': '7.1'} + + self.assertEqual(get_version(DummyRedis()), (7, 1, 0)) + + # Parses 2 digit float version numbers correctly (Seen in AWS ElastiCache Redis) + class DummyRedis(Redis): + def info(*args): + return {'redis_version': 7.1} + + self.assertEqual(get_version(DummyRedis()), (7, 1, 0)) + def test_get_redis_version_gets_cached(self): """Ensure get_version works properly""" # Parses 3 digit version numbers correctly