Skip to content

Commit 4528726

Browse files
ING-XIAOJIANdvora-h
authored andcommitted
Fix possible pipeline connections leak (#3104)
* Update cluster.py When Executing "n.write()" may generate some unknown errors(e.g. DataError), which could result in the connection not being released. * Update cluster.py * Update cluster.py release connection move to "try...finally" * Update cluster.py fix the linters * fix problems of code review
1 parent 316667e commit 4528726

File tree

1 file changed

+28
-26
lines changed

1 file changed

+28
-26
lines changed

redis/cluster.py

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2153,32 +2153,34 @@ def _send_cluster_commands(
21532153
# we dont' multiplex on the sockets as they come available,
21542154
# but that shouldn't make too much difference.
21552155
node_commands = nodes.values()
2156-
for n in node_commands:
2157-
n.write()
2158-
2159-
for n in node_commands:
2160-
n.read()
2161-
2162-
# release all of the redis connections we allocated earlier
2163-
# back into the connection pool.
2164-
# we used to do this step as part of a try/finally block,
2165-
# but it is really dangerous to
2166-
# release connections back into the pool if for some
2167-
# reason the socket has data still left in it
2168-
# from a previous operation. The write and
2169-
# read operations already have try/catch around them for
2170-
# all known types of errors including connection
2171-
# and socket level errors.
2172-
# So if we hit an exception, something really bad
2173-
# happened and putting any oF
2174-
# these connections back into the pool is a very bad idea.
2175-
# the socket might have unread buffer still sitting in it,
2176-
# and then the next time we read from it we pass the
2177-
# buffered result back from a previous command and
2178-
# every single request after to that connection will always get
2179-
# a mismatched result.
2180-
for n in nodes.values():
2181-
n.connection_pool.release(n.connection)
2156+
try:
2157+
node_commands = nodes.values()
2158+
for n in node_commands:
2159+
n.write()
2160+
2161+
for n in node_commands:
2162+
n.read()
2163+
finally:
2164+
# release all of the redis connections we allocated earlier
2165+
# back into the connection pool.
2166+
# we used to do this step as part of a try/finally block,
2167+
# but it is really dangerous to
2168+
# release connections back into the pool if for some
2169+
# reason the socket has data still left in it
2170+
# from a previous operation. The write and
2171+
# read operations already have try/catch around them for
2172+
# all known types of errors including connection
2173+
# and socket level errors.
2174+
# So if we hit an exception, something really bad
2175+
# happened and putting any oF
2176+
# these connections back into the pool is a very bad idea.
2177+
# the socket might have unread buffer still sitting in it,
2178+
# and then the next time we read from it we pass the
2179+
# buffered result back from a previous command and
2180+
# every single request after to that connection will always get
2181+
# a mismatched result.
2182+
for n in nodes.values():
2183+
n.connection_pool.release(n.connection)
21822184

21832185
# if the response isn't an exception it is a
21842186
# valid response from the node

0 commit comments

Comments
 (0)