@@ -25,12 +25,15 @@ import datetime
import time
import operator
import codecs
+import weakref
from email import message_from_file
from email.header import Header, decode_header
from email.parser import HeaderParser
from email.utils import parsedate_tz, mktime_tz
import logging
+from patchwork import lock as lockmod
+from patchwork.lock import release
from patchwork.parser import parse_patch
from patchwork.models import Patch, Project, Person, Comment, State, Series, \
SeriesRevision, SeriesRevisionPatch, get_default_initial_patch_state, \
@@ -701,11 +704,26 @@ def setup_error_handler():
return logger
+_lockref = None
+def lock():
+ global _lockref
+
+ l = _lockref and _lockref()
+ if l is not None and l.held:
+ l.lock()
+ return l
+
+ l = lockmod.lock("/tmp/patchwork.parsemail.lock", timeout=30)
+ _lockref = weakref.ref(l)
+ return l
+
def main(args):
django.setup()
logger = setup_error_handler()
mail = message_from_file(sys.stdin)
+ parse_lock = None
try:
+ parse_lock = lock()
return parse_mail(mail)
except:
if logger:
@@ -713,6 +731,8 @@ def main(args):
'mail': mail.as_string(),
})
raise
+ finally:
+ release(parse_lock)
if __name__ == '__main__':
sys.exit(main(sys.argv))
With the series support in production, I realized that postfix did not serialize the spawing of parsemail.sh. I couldn't find clear documentation about that specific case: serializing mail delivery to a mailbox is possible, not sure when postfix is piping the mail to a another process. Instead of digging further and look at postfix code, implementing the serialization in parsemail.py itself seemed like a good idea: this will work independently to the MTA used. Not only that, but it'd also work if we do crazy things like allowing to submit patches through another entry point. Signed-off-by: Damien Lespiau <damien.lespiau@intel.com> --- patchwork/bin/parsemail.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)