Skip to content

Commit fbf47b8

Browse files
committed
parser: don't fail on multiple SeriesReferences
Parallel parsing would occasonally fail with: patchwork.models.MultipleObjectsReturned: get() returned more than one SeriesReference -- it returned 2! I think these are happening if you have different processes parsing e.g. 1/3 and 2/3 simultaneously: both will have a reference to 1/3, in the case of 1 it will be the msgid, in the case of 2 it will be in References. So when we come to parse 3/3, .get() finds 2 and throws the exception. This does not fix the creation of multiple series references; it just causes them to be ignored. We still have serious race conditions with series creation, but I don't yet have clear answers for them. With this patch, they will at least not stop patches from being processed - they'll just lead to wonky series, which we already have. Reviewed-by: Andrew Donnellan <[email protected]> Signed-off-by: Daniel Axtens <[email protected]>
1 parent d438670 commit fbf47b8

File tree

1 file changed

+21
-2
lines changed

1 file changed

+21
-2
lines changed

patchwork/parser.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,13 @@ def _find_series_by_references(project, mail):
236236
msgid=ref[:255], series__project=project).series
237237
except SeriesReference.DoesNotExist:
238238
continue
239+
except SeriesReference.MultipleObjectsReturned:
240+
# FIXME: Open bug: this can happen when we're processing
241+
# messages in parallel. Pick the first and log.
242+
logger.error("Multiple SeriesReferences for %s in project %s!" %
243+
(ref[:255], project.name))
244+
return SeriesReference.objects.filter(
245+
msgid=ref[:255], series__project=project).first().series
239246

240247

241248
def _find_series_by_markers(project, mail, author):
@@ -1033,6 +1040,9 @@ def parse_mail(mail, list_id=None):
10331040
series__project=project)
10341041
except SeriesReference.DoesNotExist:
10351042
SeriesReference.objects.create(series=series, msgid=ref)
1043+
except SeriesReference.MultipleObjectsReturned:
1044+
logger.error("Multiple SeriesReferences for %s"
1045+
" in project %s!" % (ref, project.name))
10361046

10371047
# add to a series if we have found one, and we have a numbered
10381048
# patch. Don't add unnumbered patches (for example diffs sent
@@ -1071,6 +1081,11 @@ def parse_mail(mail, list_id=None):
10711081
msgid=msgid, series__project=project).series
10721082
except SeriesReference.DoesNotExist:
10731083
series = None
1084+
except SeriesReference.MultipleObjectsReturned:
1085+
logger.error("Multiple SeriesReferences for %s"
1086+
" in project %s!" % (msgid, project.name))
1087+
series = SeriesReference.objects.filter(
1088+
msgid=msgid, series__project=project).first().series
10741089

10751090
if not series:
10761091
series = Series(project=project,
@@ -1083,8 +1098,12 @@ def parse_mail(mail, list_id=None):
10831098
# we don't save the in-reply-to or references fields
10841099
# for a cover letter, as they can't refer to the same
10851100
# series
1086-
SeriesReference.objects.get_or_create(series=series,
1087-
msgid=msgid)
1101+
try:
1102+
SeriesReference.objects.get_or_create(series=series,
1103+
msgid=msgid)
1104+
except SeriesReference.MultipleObjectsReturned:
1105+
logger.error("Multiple SeriesReferences for %s"
1106+
" in project %s!" % (msgid, project.name))
10881107

10891108
cover_letter = CoverLetter(
10901109
msgid=msgid,

0 commit comments

Comments
 (0)