Skip to content
This repository has been archived by the owner on Jan 9, 2024. It is now read-only.

Stop leaking connections when pool is full #473

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

FranGM
Copy link
Contributor

@FranGM FranGM commented Jul 19, 2021

Fixes #458

When our connection pool is full (there are no available connections) we
can run into a case where we leak perfectly useable connections. This
essentially reduces the size of our connection pool every time it
happens, as it can slowly leak away our unused connections until we
don't have enough connections available to cope with our workload.

This is particularly problematic when preparing connections for a
pipeline, since we can potentially request (and leak) a large number of
connections in one go.

This change makes sure that before raising an exception if there are no
available connections we return back all connections we've checked to
the pool. In cases where we can't guarantee the connections we'd return
to the pool are in a safe state we just add back None objects to the
pool so at least the effective size of the connection pool remains
unchanged.

When our connection pool is full (there are no available connections) we
can run into a case where we leak perfectly useable connections. This
essentially reduces the size of our connection pool every time it
happens, as it can slowly leak away our unused connections until we
don't have enough connections available to cope with our workload.

This is particularly problematic when preparing connections for a
pipeline, since we can potentially request (and leak) a large number of
connections in one go.

This change makes sure that before raising an exception if there are no
available connections we return back all connections we've checked to
the pool. In cases where we can't guarantee the connections we'd return
to the pool are in a safe state we just add back `None` objects to the
pool so at least the effective size of the connection pool remains
unchanged.
# If we don't add it back to the pool it shouldn't count towards the
# connection pool, or we'll artificially reduce the maximum size of the
# pool
self._created_connections_per_node.setdefault(node['name'], 0)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self._created_connections_per_node.setdefault(node['name'], 0)
self._created_connections_per_node.setdefault(connection.node['name'], 0)

try:
nodes[node_name] = NodeCommands(self.parse_response, self.connection_pool.get_connection_by_node(node))
except:
# Sommething happened, maybe the pool is full, we need to release any connection

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo:

Suggested change
# Sommething happened, maybe the pool is full, we need to release any connection
# Something happened, maybe the pool is full, we need to release any connection

"""
Releases the connection back to the pool
"""
self._checkpid()
if connection.pid != self.pid:
return

# In some cases we don't want to add back this connection to the pool but
# we still want to free its slot

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# we still want to free its slot
# we still want to free its slot (a None represents an available connection
# pool slot)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Possible connection leak in ClusterBlockingConnectionPool
2 participants