diff --git a/rq/utils.py b/rq/utils.py index 7528c10c..5752976f 100644 --- a/rq/utils.py +++ b/rq/utils.py @@ -303,7 +303,14 @@ def get_version(connection: 'Redis'): connection (Redis): The Redis connection. """ try: - return tuple(int(i) for i in connection.info("server")["redis_version"].split('.')[:3]) + # 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): + setattr( + connection, + "__rq_redis_server_version", + tuple(int(i) for i in connection.info("server")["redis_version"].split('.')[:3]) + ) + return getattr(connection, "__rq_redis_server_version") except ResponseError: # fakeredis doesn't implement Redis' INFO command return (5, 0, 9) diff --git a/tests/test_utils.py b/tests/test_utils.py index b9cb2024..64b3f64a 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,5 +1,6 @@ import re import datetime +from unittest.mock import Mock from redis import Redis @@ -85,6 +86,15 @@ class TestUtils(RQTestCase): return {'redis_version': '3.0.7.9'} self.assertEqual(get_version(DummyRedis()), (3, 0, 7)) + def test_get_redis_version_gets_cached(self): + """Ensure get_version works properly""" + # Parses 3 digit version numbers correctly + redis = Mock(spec=['info']) + redis.info = Mock(return_value={'redis_version': '4.0.8'}) + self.assertEqual(get_version(redis), (4, 0, 8)) + self.assertEqual(get_version(redis), (4, 0, 8)) + redis.info.assert_called_once() + def test_ceildiv_even(self): """When a number is evenly divisible by another ceildiv returns the quotient""" dividend = 12