44
55import aioredis
66
7- __all__ = ['RedisSession' , 'RedisSessionClosed ' , 'RedisSessionNotInitialized ' ]
7+ __all__ = ['RedisSession' , 'RedisSessionNotInitialized ' , 'RedisSessionNotConnected ' ]
88
99log = logging .getLogger (__name__ )
1010
@@ -13,8 +13,8 @@ class RedisSessionNotInitialized(RuntimeError):
1313 """Raised when the RedisSession instance has not been initialized yet."""
1414
1515
16- class RedisSessionClosed (RuntimeError ):
17- """Exception raised when something attempts operations on a closed redis session ."""
16+ class RedisSessionNotConnected (RuntimeError ):
17+ """Raised when trying to access the Redis client before a connection has been created ."""
1818
1919
2020class FakeRedisNotInstalled (ImportError ):
@@ -55,22 +55,26 @@ class RedisSession(metaclass=RedisSingleton):
5555 creates it, run the loop until the `connect` coroutine is completed, and
5656 passing the loop to `discord.ext.commands.Bot.__init__` afterwards.
5757
58+ The `url` argument, and kwargs are passed directly to the `aioredis.from_url` method.
59+
5860 Example:
59- redis_session = RedisSession()
61+ redis_session = RedisSession("redis://localhost" )
6062 loop = asyncio.get_event_loop()
61- loop.run_until_complete(redis_session.connect(... ))
63+ loop.run_until_complete(redis_session.connect())
6264 bot = discord.ext.commands.Bot(..., loop=loop)
6365 """
6466
6567 _instance : RedisSession = None
6668
6769 def __init__ (
68- self , * , global_namespace : str = "" , use_fakeredis : bool = False , ** session_kwargs
70+ self , url : str , * , global_namespace : str = "" , use_fakeredis : bool = False , ** session_kwargs
6971 ) -> None :
7072 self .global_namespace = global_namespace
71- self ._pool = None
73+ self .url = url
74+ self ._client = None
7275 self ._session_kwargs = session_kwargs
7376 self ._use_fakeredis = use_fakeredis
77+ self .connected = False
7478
7579 @classmethod
7680 def get_current_session (cls ) -> RedisSession :
@@ -86,28 +90,22 @@ def get_current_session(cls) -> RedisSession:
8690 return cls ._instance
8791
8892 @property
89- def pool (self ) -> aioredis .Redis :
93+ def client (self ) -> aioredis .Redis :
9094 """
91- Get the connection pool after checking if it is still connected .
95+ Get the redis client object to perform commands on .
9296
93- This property will raise a `RedisSessionClosed ` if it's accessed after
94- the pool has been closed .
97+ This property will raise a `RedisSessionNotConnected ` if it is accessed
98+ before the connect method is called .
9599 """
96- if self ._pool . closed :
97- raise RedisSessionClosed (
98- "attempting to access connections pool after it has been closed ."
100+ if not self .connected :
101+ raise RedisSessionNotConnected (
102+ "attempting to access the client before the connection has been created ."
99103 )
100-
101- return self ._pool
102-
103- @property
104- def closed (self ) -> bool :
105- """Return whether or not the RedisSession is closed."""
106- return self ._pool is None or self ._pool .closed
104+ return self ._client
107105
108106 async def connect (self ) -> None :
109- """Connect to Redis by creating the connections pool ."""
110- log .debug ("Creating Redis connections pool ." )
107+ """Connect to Redis by instantiating the redis instance ."""
108+ log .debug ("Creating Redis client ." )
111109
112110 # Decide if we want to use `fakeredis` or an actual Redis server. The
113111 # option to use `fakeredis.aioredis` is provided to aid with running the
@@ -126,18 +124,20 @@ async def connect(self) -> None:
126124 )
127125
128126 kwargs = dict (self ._session_kwargs )
127+ # Match the behavior of `aioredis.from_url` by updating the kwargs using the URL
128+ url_options = aioredis .connection .parse_url (self .url )
129+ kwargs .update (dict (url_options ))
129130
130- # the `address` and `password` kwargs are not supported by redis
131- kwargs .pop ("address" , None )
132- kwargs .pop ("password" , None )
131+ # The following kwargs are not supported by fakeredis
132+ [kwargs .pop (kwarg , None ) for kwarg in (
133+ "address" , "username" , "password" , "port" , "timeout"
134+ )]
133135
134- pool_constructor = fakeredis .aioredis .create_redis_pool (** kwargs )
136+ self . _client = fakeredis .aioredis .FakeRedis (** kwargs )
135137 else :
136- pool_constructor = aioredis .create_redis_pool (** self ._session_kwargs )
137-
138- self ._pool = await pool_constructor
138+ self ._client = aioredis .from_url (self .url , ** self ._session_kwargs )
139139
140- async def close ( self ) -> None :
141- """Close the pool and wait for pending operations to be processed."""
142- self ._pool . close ()
143- await self ._pool . wait_closed ()
140+ # The connection pool client does not expose any way to connect to the server, so
141+ # we try to perform a request to confirm the connection
142+ await self ._client . ping ()
143+ self .connected = True
0 commit comments