[Checkins] SVN: Zope/branches/2.12/ Ensure that mailhosts which share a queue directory do not double-deliver mails.

Tres Seaver tseaver at palladion.com
Mon May 3 12:24:33 EDT 2010


Log message for revision 111900:
  Ensure that mailhosts which share a queue directory do not double-deliver mails.
  
  Do this by sharing the thread which processes emails for that directory.
  
  Fixes LP #574286
  

Changed:
  U   Zope/branches/2.12/doc/CHANGES.rst
  U   Zope/branches/2.12/src/Products/MailHost/MailHost.py
  U   Zope/branches/2.12/src/Products/MailHost/tests/testMailHost.py

-=-
Modified: Zope/branches/2.12/doc/CHANGES.rst
===================================================================
--- Zope/branches/2.12/doc/CHANGES.rst	2010-05-03 16:24:30 UTC (rev 111899)
+++ Zope/branches/2.12/doc/CHANGES.rst	2010-05-03 16:24:32 UTC (rev 111900)
@@ -36,6 +36,10 @@
 Bugs Fixed
 ++++++++++
 
+- LP #574286:  Ensure that mailhosts which share a queue directory do not
+  double-deliver mails, by sharing the thread which processes emails for
+  that directory.
+
 - BaseRequest: Fixed handling of errors in 'traverseName'.
 
 2.12.5 (2010-04-24)

Modified: Zope/branches/2.12/src/Products/MailHost/MailHost.py
===================================================================
--- Zope/branches/2.12/src/Products/MailHost/MailHost.py	2010-05-03 16:24:30 UTC (rev 111899)
+++ Zope/branches/2.12/src/Products/MailHost/MailHost.py	2010-05-03 16:24:32 UTC (rev 111900)
@@ -15,6 +15,7 @@
 $Id$
 """
 import logging
+from os.path import realpath
 import re
 from cStringIO import StringIO
 from copy import deepcopy
@@ -266,32 +267,38 @@
                           force_tls=self.force_tls
                          )
 
+    security.declarePrivate('_getThreadKey')
+    def _getThreadKey(self):
+        """ Return the key used to find our processor thread.
+        """
+        return realpath(self.smtp_queue_directory)
+
     @synchronized(lock)
     def _stopQueueProcessorThread(self):
-        """ Stop thread for processing the mail queue """
-
-        path = self.absolute_url(1)
-        if queue_threads.has_key(path):
-            thread = queue_threads[path]
+        """ Stop thread for processing the mail queue.
+        """
+        key = self._getThreadKey()
+        if queue_threads.has_key(key):
+            thread = queue_threads[key]
             thread.stop()
             while thread.isAlive():
                 # wait until thread is really dead
                 time.sleep(0.3)
             del queue_threads[path]
-            LOG.info('Thread for %s stopped' % path)
+            LOG.info('Thread for %s stopped' % key)
 
     @synchronized(lock)
     def _startQueueProcessorThread(self):
-        """ Start thread for processing the mail queue """
-
-        path = self.absolute_url(1)
-        if not queue_threads.has_key(path):
+        """ Start thread for processing the mail queue.
+        """
+        key = self._getThreadKey()
+        if not queue_threads.has_key(key):
             thread = QueueProcessorThread()
             thread.setMailer(self._makeMailer())
             thread.setQueuePath(self.smtp_queue_directory)
             thread.start()
-            queue_threads[path] = thread     
-            LOG.info('Thread for %s started' % path)
+            queue_threads[key] = thread     
+            LOG.info('Thread for %s started' % key)
 
     security.declareProtected(view, 'queueLength')
     def queueLength(self):
@@ -307,9 +314,9 @@
 
     security.declareProtected(view, 'queueThreadAlive')
     def queueThreadAlive(self):
-        """ return True/False is queue thread is working """
-
-        th = queue_threads.get(self.absolute_url(1))
+        """ return True/False is queue thread is working
+        """
+        th = queue_threads.get(self._getThreadKey())
         if th:
             return th.isAlive()
         return False

Modified: Zope/branches/2.12/src/Products/MailHost/tests/testMailHost.py
===================================================================
--- Zope/branches/2.12/src/Products/MailHost/tests/testMailHost.py	2010-05-03 16:24:30 UTC (rev 111899)
+++ Zope/branches/2.12/src/Products/MailHost/tests/testMailHost.py	2010-05-03 16:24:32 UTC (rev 111900)
@@ -110,6 +110,14 @@
         self.failUnlessEqual(resto, ['many at example.com'])
         self.failUnlessEqual(resfrom, 'me at example.com' )
 
+    def test__getThreadKey_uses_fspath(self):
+        mh1 = self._makeOne('mh1')
+        mh1.smtp_queue_directory = '/abc'
+        mh1.absolute_url = lambda self: 'http://example.com/mh1'
+        mh2 = self._makeOne('mh2')
+        mh2.smtp_queue_directory = '/abc'
+        mh2.absolute_url = lambda self: 'http://example.com/mh2'
+        self.assertEqual(mh1._getThreadKey(), mh2._getThreadKey())
 
     def testAddressParser( self ):
         msg = """To: "Name, Nick" <recipient at domain.com>, "Foo Bar" <foo at domain.com>



More information about the checkins mailing list