[spambayes-dev] imap filter not closing sockets

Sjoerd Mullender sjoerd at acm.org
Wed May 7 22:52:49 CEST 2008


If you run sb_imapfilter.py in daemon mode (i.e. with -l option) and you 
use IMAPS to talk to the IMAP server, it will slowly eat up file 
descriptors, and all open file descriptors will be sockets in CLOSE_WAIT 
state.

At the end of the run() function there is the main loop which starts a 
new IMAPSession in each iteration, but if you look closely, you'll see 
that it also calls logout() on each session, and logout closes the imap 
session (and the socket).  So all seems right.

However, the Python library doesn't actually close the socket!  It only 
removes a reference to the socket, and if the number of references drops 
to zero, the socket is really closed.  If you use IMAPS (as opposed to 
plain IMAP), the SSL layer apparently adds a reference which is not 
destroyed, so the ref count doesn't reach zero, so the socket isn't closed.

I propose that we change the logout method of IMAPSession to explicitly 
reach into the socket object and close the socket:

Index: sb_imapfilter.py
===================================================================
--- sb_imapfilter.py    (revision 3176)
+++ sb_imapfilter.py    (working copy)
@@ -293,7 +293,9 @@
                  for fol in options["imap", fol_list]:
                      self.select(fol)
                      self.expunge()
+        s = self.sock._sock
          BaseIMAP.logout(self)  # superclass logout
+        s.close()

      def check_response(self, command, IMAP_response):
          """A utility function to check the response from IMAP commands.

For more info, see the thread I started today on python-dev.

-- 
Sjoerd Mullender


More information about the spambayes-dev mailing list