I changed the code of a filter which is already configured and running.  Now I
have to install it.  Last time I issued courierfilter stop, and then start.
However, that way I have to reload also clamav databases, which takes a long
time.  Is there any better way to upgrade the running Python process?

BTW, in order to tell distributed filter from home-brewed ones, I install sym
links in the dist-package/pythonfilter directory, which point to the source
file.  I note that Python does not produce any .pyc in that case.  However, the
following command compiles in the current directory irrespectively of whatever:

    python -m compileall -l attachments.py

Since the pyc is what should get loaded when loading a module, an idea could be
to reload modules if they have been recompiled since the last time they were
loaded.  Let me attach the idea.  Beware: I did'n run it, not even once, and
didn't fully understand the caveats about using reload(), see e.g.:


One more question, about virtualenv.  Has anyone had experience loading
Pythonfilter that way under Courier?  Another possibility is to install
Pythonfilter globally, but keep additional packages in a virtualenv, just to
ease tracking requirements.


    2016-10-31 17:21:05.543243721 +0100
+++ ../pythonfilter-modified-but-not-tested.py  2017-06-07 13:09:59.818621251 
@@ -111,6 +111,11 @@
                          (importError[0], importError[1]))
+    try:
+        moduleDate = os.stat(module.__file__).st_mtime
+    except OSError:
+        moduleDate = None
     if hasattr(module, 'initFilter'):
@@ -126,7 +131,7 @@
         # Store the name of the filter module and a reference to its
         # dofilter function in the "filters" array.
-        filters.append((moduleName, module.doFilter, bypass))
+        filters.append((moduleName, module.doFilter, bypass, module, 
     except AttributeError:
         # Log bad modules
         importError = sys.exc_info()
@@ -203,13 +208,23 @@
     # Prepare a set of filters that will not be run if a module returns
     # a 2XX code, and specifies a list of filters to bypass.
     bypass = set()
-    for i_filter in filters:
+    for i_i, i_filter in enumerate(filters):
         # name = i_filter[0]
         # function = i_filter[1]
         # bypass = i_filter[2]
         if i_filter[0] in bypass:
+            if i_filter[4] is not None:
+                moduleDate = os.stat(i_filter[3].__file__).st_mtime
+                if moduleDate > i_filter[4]:
+                    reload(i_filter[3])
+                    i_filter[4] = moduleDate
+                    filters[i_i] = (i_filter[0], i_filter[1], i_filter[2], 
i_filter[3], i_filter[4])
+                    sys.stderr.write('Reloaded %s\n' % i_filter[0])
+        except:
+            sys.stderr.write('Not reloaded %s\n' % i_filter[0])
+        try:
             replyCode = i_filter[1](bodyFile, controlFileList)
             filterError = sys.exc_info()

Attachment: signature.asc
Description: OpenPGP digital signature

Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
courier-users mailing list
Unsubscribe: https://lists.sourceforge.net/lists/listinfo/courier-users

Reply via email to