Skip to content
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

Fix socket garbage collection #2859

Merged
merged 11 commits into from
Jul 31, 2023

Conversation

kristjanvalur
Copy link
Contributor

@kristjanvalur kristjanvalur commented Jul 19, 2023

Pull Request check-list

Please make sure to review and check all of these items:

  • Does $ tox pass with this change (including linting)?
  • Do the CI tests pass with this change (enable it first in your forked repo and wait for the github action build to finish)?
  • Is the new or changed code fully tested?
  • Is a documentation update included (if this change modifies existing APIs, or introduces new ones)?
  • Is there an example added to the examples folder (if applicable)?
  • Was the change added to CHANGES file?

NOTE: these things are not required to open a PR and can be done
afterwards / while the PR is open.

Description of change

Issue #2831 shows how connections are kept open when they are simply discarded.
The problem is two-fold:

  1. Redis connections opened with from-url don't have their auto_close_connection boolean set to True, as is the default for a pool which is created automatically. Therefore, when Redis.close() was called, the pool would not close its collections.
  2. Even so, garbage collection of the Connection objects ought to have closed the sockets associated with the underlying StreamWriter objects. This apparently does not reliably happen, so we re-instate a __del__ handler for the AbstractConnection which does the bare minimum required, calling StreamWriter.close().
  3. Add an auto_close_connection_pool argument to asyncio.Redis.from_url() which defaults to true, same as for asyncio.Redis()

A fix was added to an unrelated test which caused unit tests to fail on non-linux platforms.

Update

I've changed the PR so as to remove the 2, above. In general for asyncio Python, socket cleanup is not done on garbage collection (since it involves async operations). Instead, it is assumed that a well written program performs proper disconnects as needed. __del__ handlers instead are used to emit warnings, that is, if a socket (or other resource) is found to be not closed when purging an object, a warning is emitted. This is to make sure resources are released properly by the application.

Fixing of (1) above ensures that the connection pool is indeed cleaned up correctly. Trying to put cleanup and IO logic into destructors is in general not thought to be a good practice and should be avoided whenever possible. Correct program operation should not rely on the prompt execution of __del__ handlers, and implementing them would deprive us of the built-in resource warnings which would otherwise be emitted.

@kristjanvalur kristjanvalur force-pushed the kristjan/disconnect branch 3 times, most recently from 703c7a6 to 05f717e Compare July 19, 2023 17:11
@codecov-commenter
Copy link

codecov-commenter commented Jul 19, 2023

Codecov Report

Patch coverage: 70.21% and project coverage change: +0.31% 🎉

Comparison is base (2732a85) 90.66% compared to head (34a69ff) 90.98%.
Report is 1 commits behind head on master.

❗ Your organization is not using the GitHub App Integration. As a result you may experience degraded service beginning May 15th. Please install the Github App Integration for your organization. Read more.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2859      +/-   ##
==========================================
+ Coverage   90.66%   90.98%   +0.31%     
==========================================
  Files         126      126              
  Lines       32229    32295      +66     
==========================================
+ Hits        29221    29384     +163     
+ Misses       3008     2911      -97     
Files Changed Coverage Δ
tests/test_connect.py 87.21% <22.22%> (-11.24%) ⬇️
redis/asyncio/client.py 91.99% <100.00%> (-0.16%) ⬇️
tests/test_asyncio/test_connection.py 92.93% <100.00%> (+1.05%) ⬆️

... and 13 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

…ConnectionPool`

Documentation specifies that the `kwargs` are pssed to `ConnectionPool` but some
arguments are not meant for it.
@kristjanvalur
Copy link
Contributor Author

@dvora-h you may want to see the latest change. Arguments intended for the "Redis" class are now explicit in from_url, while the kwargs get passed to the ConnectionPool constructor. This makes the docstring more correct.

@chayim chayim merged commit 8e5d5ce into redis:master Jul 31, 2023
@chayim chayim mentioned this pull request Jul 31, 2023
6 tasks
@kristjanvalur kristjanvalur deleted the kristjan/disconnect branch July 31, 2023 10:15
chayim pushed a commit that referenced this pull request Aug 31, 2023
Co-authored-by: Viktor Ivanov <viktor@infogrid.io>
Co-authored-by: Sergey Prokazov <sergey.prokazov@redis.com>
Co-authored-by: Anuragkillswitch <70265851+Anuragkillswitch@users.noreply.github.com>
Co-authored-by: dvora-h <67596500+dvora-h@users.noreply.github.com>
Co-authored-by: Alex Schmitz <aschmitz@box.com>
Co-authored-by: Alex Schmitz <alex.schmitz@gmail.com>
Co-authored-by: Chayim <chayim@users.noreply.github.com>
Co-authored-by: Bar Shaul <88437685+barshaul@users.noreply.github.com>
Co-authored-by: CrimsonGlory <CrimsonGlory@users.noreply.github.com>
Co-authored-by: Raymond Yin <raymond@tryevergreen.com>
Co-authored-by: zach.lee <zach.lee@sendbird.com>
Co-authored-by: James R T <jamestiotio@gmail.com>
Co-authored-by: dvora-h <dvora.heller@redis.com>
Co-authored-by: Marc Schöchlin <marc.schoechlin@flipapp.de>
Co-authored-by: Nick Gerow <nick.gerow@enlightedinc.com>
Co-authored-by: Igor Malinovskiy <u.glide@gmail.com>
Co-authored-by: Chayim I. Kirshen <c@kirshen.com>
Co-authored-by: Leibale Eidelman <me@leibale.com>
Co-authored-by: Thiago Bellini Ribeiro <hackedbellini@gmail.com>
Co-authored-by: woutdenolf <woutdenolf@users.sf.net>
Co-authored-by: shacharPash <93581407+shacharPash@users.noreply.github.com>
Co-authored-by: Mirek Długosz <miniopl+github@gmail.com>
Co-authored-by: Oran Avraham <252748+oranav@users.noreply.github.com>
Co-authored-by: mzdehbashi-github <85902780+mzdehbashi-github@users.noreply.github.com>
Co-authored-by: Tyler Hutcherson <tyler.hutcherson@redis.com>
Co-authored-by: Felipe Machado <462154+felipou@users.noreply.github.com>
Co-authored-by: AYMEN Mohammed <53928879+AYMENJD@users.noreply.github.com>
Co-authored-by: Marc Schöchlin <ms-github@256bit.org>
Co-authored-by: Avasam <samuel.06@hotmail.com>
Co-authored-by: Markus Gerstel <2102431+Anthchirp@users.noreply.github.com>
Co-authored-by: Kristján Valur Jónsson <sweskman@gmail.com>
Co-authored-by: Nick Gerow <Nick.G.123@hotmail.com>
Co-authored-by: Cristian Matache <cristianmatache@hotmail.com>
Co-authored-by: Anurag Bandyopadhyay <angbpy@gmail.com>
Co-authored-by: Seongchuel Ahn <aciddust20@gmail.com>
Co-authored-by: Alibi <aliby.bbb@gmail.com>
Co-authored-by: Smit Parmar <smitraj333@gmail.com>
Co-authored-by: Brad MacPhee <macphee@gmail.com>
Co-authored-by: Shahar Lev <shahar_lev@hotmail.com>
Co-authored-by: Vladimir Mihailenco <vladimir.webdev@gmail.com>
Co-authored-by: Kevin James <KevinJames@thekev.in>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: David Pacsuta <34983281+ant1fact@users.noreply.github.com>
Co-authored-by: Rich Bowen <rbowen@rcbowen.com>
Co-authored-by: gmbnomis <gmbnomis@users.noreply.github.com>
Co-authored-by: Vivanov98 <66319645+Vivanov98@users.noreply.github.com>
Co-authored-by: Kosuke <kosuke.zhang@gmail.com>
Co-authored-by: Sergey Prokazov <prokazov@users.noreply.github.com>
Co-authored-by: jmcbailey <jmcbailey@gmail.com>
Co-authored-by: Galtozzy <14139502+Galtozzy@users.noreply.github.com>
Co-authored-by: Abhishek Kumar Sinha <aksinha334@gmail.com>
Co-authored-by: Eom Taegyung "Iggy <iggy.eom@sendbird.com>
Co-authored-by: Mehdi ABAAKOUK <sileht@sileht.net>
Co-authored-by: Dongkeun Lee <3315213+zakaf@users.noreply.github.com>
Co-authored-by: woutdenolf <wout.de_nolf@esrf.eu>
Co-authored-by: Kurt McKee <contactme@kurtmckee.org>
Co-authored-by: Juraj Páll <palljuraj1@gmail.com>
Co-authored-by: Joan Fontanals <jfontanalsmartinez@gmail.com>
Co-authored-by: Stanislav Zmiev <zmievsa@gmail.com>
fix (#2566)
Fix unlink in cluster pipeline (#2562)
Fix issue 2540: Synchronise concurrent command calls to single-client mode. (#2568)
Fix: tuple function cannot be passed more than one argument (#2573)
Fix issue 2567: NoneType check before raising exception (#2569)
Fix issue 2349: Let async HiredisParser finish parsing after a Connection.disconnect() (#2557)
Fix issue with `pack_commands` returning an empty byte sequence (#2416)
Fix #2581 UnixDomainSocketConnection' object has no attribute '_command_packer' (#2583)
Fix #2581 UnixDomainSocketConnection' object has no attribute '_command_packer' .
Fix for `lpop` and `rpop` return typing (#2590)
Fixed CredentialsProvider examples (#2587)
Fixed issue #2598 - make Document class subscriptable
fix: replace async_timeout by asyncio.timeout (#2602)
Fix behaviour of async PythonParser to match RedisParser as for issue #2349 (#2582)
Fix (#2641)
fix: do not use asyncio's timeout lib before 3.11.2 (#2659)
Fix issue 2660: PytestUnraisableExceptionWarning from asycio client (#2669)
Fixing cancelled async futures (#2666)
Fix async (#2673)
Fix memory leak caused by hiredis (#2693) (#2694)
Fix incorrect usage of once flag in async Sentinel (#2718)
Fix topk list example. (#2724)
Fix `ClusterCommandProtocol` not itself being marked as a protocol (#2729)
Fix potential race condition during disconnection (#2719)
fix CI (#2748)
fix parse_slowlog_get (#2732)
fixes for issue #1128
fix create single_connection_client from url (#2752)
Fix `xadd` allow non negative maxlen (#2739)
Fix JSON.MERGE Summary (#2786)
Fixed key error in parse_xinfo_stream (#2788)
Fix dead weakref in sentinel connection causing ReferenceError (#2767) (#2771)
Fix dead weakref in sentinel conn (#2767)
fix redirects and some small cleanups (#2801)
Fix type hint for retry_on_error in async cluster (#2804)
Fix CI (#2809)
Fix async client with resp3 (#2657)
Fix `COMMAND` response in resp3 (redis 7+) (#2740)
Fix protocol version checking (#2737)
Fix parse resp3 dict response: don't use dict comprehension (#2757)
Fixing asyncio import (#2759)
fix (#2799)
fix async tests (#2806)
Fix socket garbage collection (#2859)
Fixing doc builds (#2869)
Fix a duplicate word in `CONTRIBUTING.md` (#2848)
Fix timeout retrying on Redis pipeline execution (#2812)
Fix type hints in SearchCommands (#2817)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants