psycopg / psycopg2

PostgreSQL database adapter for the Python programming language
https://www.psycopg.org/
Other
3.35k stars 506 forks source link

LoggingConnection keeps connections open even after the Garbage Collector is run #1670

Open spatankar-dmpna opened 8 months ago

spatankar-dmpna commented 8 months ago

Please complete the following information:

Describe the bug Please let us know:

1: what you did We have subclassed LoggingConnection and LoggingCursor for our project. In our initial design we were relying on the garbage collectors to close our connection at the end of the function scopes. This was bad design and has since been fixed. 2: what you expected to happen The garbage collector should have destroyed the LoggingConnection object at the end the function scope. 3: what happened instead The LoggingConnection object remained alive because it still had a reference to it.

Explanation:

Looking into the issue, it looks like the LoggingConnection still had a reference to it because of the bound method "log"

`

def initialize(self,  logobj):
    self._logobj = logobj
    if _logging and isinstance(logobj, (_logging.Logger, _logging.LoggerAdapter)):
         self.log = self._logtologger
    else:
        self.log = self._logtofile

`

The Solution:

The methods should be bound with a weak reference instead

`

def initialize(self, logobj):
    self._logobj = logobj
    if _logging and isinstance(logobj, (_logging.Logger, _logging.LoggerAdapter)):
        self._log = weakref.WeakMethod(self._logtologger)
   else:
        self._log = weakref.WeakMethod(self._logtofile)

def log(self, *args, **kwargs):
   return self._log()(*args, **kwargs)

`