ghettoq icon indicating copy to clipboard operation
ghettoq copied to clipboard

MutliBackend's monkey patching of `drain_events` leads to connection leaks

Open wolever opened this issue 14 years ago • 0 comments

In the establish_connection method of MultiBackend, it monkey patches the connection's drain_events method:

def establish_connection(self):
    conninfo = self.connection
    conn = Connection(self.type, host=conninfo.hostname,
                                 user=conninfo.userid,
                                 password=conninfo.password,
                                 database=conninfo.virtual_host,
                                 port=conninfo.port)
    conn.drain_events = self.drain_events # << here   
    return conn                 

But this leads to problems, because MultiBackend.drain_events method calls MutiBackend.channel, which opens up a new connection… But there is no reference to that connection from the connection returned by establish_connection.

For example:

>>> conn = establish_connection.establish_connection()
>>> conn.drain_events() # creates a new connection
...
>>> conn.close()

This code looks correct, but will in fact leave a dangling connection (ie, the one created during drain_events).

This is a problem because carrot.connection.BrokerConnection._establish_connection is:

def _establish_connection(self):
    return self.create_backend().establish_connection()

Which means that a backend is being created, but no reference is kept to it. So, for example:

>>> conn = broker._establish_connection().drain_events()
>>> conn.drain_events()
>>> conn.close()

Will leave a dangling connection with no direct references (ie, because the only reference is through conn.drain_events).

wolever avatar Nov 15 '10 00:11 wolever