-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Redis.from_pool()
class method, for explicitly owning and closing a ConnectionPool
#2913
Conversation
Redis.from_pool()
class method, for explicitly owning and closing a ConnectionPool
32f13ef
to
d59e207
Compare
Codecov ReportPatch coverage:
❗ Your organization needs to install the Codecov GitHub app to enable full functionality. Additional details and impacted files@@ Coverage Diff @@
## master #2913 +/- ##
==========================================
+ Coverage 91.35% 91.38% +0.02%
==========================================
Files 126 126
Lines 32335 32469 +134
==========================================
+ Hits 29540 29671 +131
- Misses 2795 2798 +3
☔ View full report in Codecov by Sentry. |
d59e207
to
e9d74ac
Compare
@@ -114,7 +114,6 @@ def from_url( | |||
cls, | |||
url: str, | |||
single_connection_client: bool = False, | |||
auto_close_connection_pool: bool = True, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This breaks the interface...
Here, my concern is primarly around breaking the connection interface. I realize that async is in flux, and frankly many things will be - but this interface is public and exposed, and not internal. Maybe there's another way - without breaking the user contract? |
I understand. I think we can leave this attribute in place. I'm sure you agree that it feels cludgy, and long. I'm re-adding it in code, along with a comment on why I think we should try to phase it out. i.e. this is a healthier pattern pool = ConnectionPool.from_url(url)
client = Redis(connection_pool=pool)
...
pool.close() rather than this: client = Redis.from_url(url, auto_close_connection_pool=False)
pool = client.connection_pool # need to fish out the pool so that we can close it later.
...
pool.close() |
e9d74ac
to
9fe68a9
Compare
I definitely agree is kludgey... I generally dislike these interface (sync and asycn.. heck even cluster). But we should break accordingly in the future. |
Redis.from_pool()
class method, for explicitly owning and closing a ConnectionPoolRedis.from_pool()
class method, for explicitly owning and closing a ConnectionPool
8fbecb1
to
32963b9
Compare
32963b9
to
b34c890
Compare
Pull Request check-list
$ tox
pass with this change (including linting)?Description of change
Traditionally, synchronous
redis-py
has relied on__del__
to disconnect anyConnectionPool
owned by aRedis
object.Explicitly closing those has been possible, via
client.connection_pool.disconnect()
, but this does not work well withusing context managers and other approaches. Relying on
__del__()
to clean up sockets is not considered good practice since it relies on the peculiarities of the particular implementation, garbage collection and such things.In async redis, a mechanism was added to make an
asyncio.Redis
object own a connection and close it, to providebetter connection over connection lifetime. This was done here:
aio-libs-abandoned/aioredis-py#1256
This mechanism carried over when that library was added to redis-py, and we increasinly rely on it to properly clean up sockets used in asynchronous mode. However, the mechanism added was cumbersome to use and overly verbose. In particular, it made it awkward to create a custom
ConnectionPool
instance, hand it to a newRedis
object, and expect it to close it automatically.This PR, aims to:
auto_close_connection_pool
ignored #2901, adding a newfrom_pool()
class method to use instead of theauto_close_connection_pool
constructor argument.auto_close_connection_pool
argument.The following now applies for both synchronous and asynchronous redis:
Redis
object created without providing aConnectionPool
instance, e.g. viaRedis()
orRedis.from_url()
, will now automatically callconnection_pool.disconnect()
whencall()
is closed.Redis
object createdRedis.from_pool()
similarly takes ownership of the pool, and will disconnect the pool.connection_pool
argument is used byRedis.__init__()
this is not done, instead it is assumed the callerwill close the pool.
Sentinel
object, will use afrom_pool()
class method constructing aRedis
object to return from themaster_for()
andslave_for()
methods.auto_close_connection_pool
Redis.__init__()
argument is not provided forredis.Redis
, but kept in place for backwards compatibility forredis.asyncio.Redis
The above behaviour is controlled by the
auto_close_connection_pool
property ofRedis
.