[PATCH 2/2] parsemail: Make parsing an email atomic operation
Damien Lespiau
damien.lespiau at intel.com
Tue Oct 20 23:08:43 AEDT 2015
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 at intel.com>
---
patchwork/bin/parsemail.py | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/patchwork/bin/parsemail.py b/patchwork/bin/parsemail.py
index ba0b148..b41475d 100755
--- a/patchwork/bin/parsemail.py
+++ b/patchwork/bin/parsemail.py
@@ -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))
--
2.4.3
More information about the Patchwork
mailing list