Skip to content

Commit 578fb26

Browse files
authored
Avoid creating ref cycles (#2932)
This won't meaningfully affect most users, so I won't feel bad if this is closed :-) It's often important for performance to control when garbage collection runs and to reduce the need to run garbage collection in the first place. During AbstractionConnection.on_connect, it's common to raise and catch ResponseError, since e.g. CLIENT SETINFO is very new. However, because response is in a local, it creates ref cycles that keep all locals in all calling stack frames alive. The use of a local to store the exception is unfortunate, since exceptions hold references to their tracebacks, which hold references to the relevant frames, which holds a reference to the local exception. See https://peps.python.org/pep-0344/#open-issue-garbage-collection and https://peps.python.org/pep-3110/#rationale This breaks the cycle by deleting the local when we raise, so frames are destroyed by the normal reference counting mechanism.
1 parent ba186d2 commit 578fb26

File tree

1 file changed

+4
-1
lines changed

1 file changed

+4
-1
lines changed

redis/connection.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,10 @@ def read_response(
513513
self.next_health_check = time() + self.health_check_interval
514514

515515
if isinstance(response, ResponseError):
516-
raise response
516+
try:
517+
raise response
518+
finally:
519+
del response # avoid creating ref cycles
517520
return response
518521

519522
def pack_command(self, *args):

0 commit comments

Comments
 (0)