Wrap the entire parse_mail() call in transaction.atomic() so that all database writes from email parsing run inside a single transaction. The existing transaction.atomic() blocks inside parse_mail() become savepoints within this outer transaction. The series deduplication retry logic continues to work since savepoint rollbacks are scoped to their own savepoint.
This also ensures that any on_commit() callbacks registered by signal handlers only fire after the full email has been parsed and all patch/series associations are committed. Signed-off-by: Robin Jarry <[email protected]> --- patchwork/management/commands/parsemail.py | 4 +++- .../notes/parsemail-transaction-d4e5f6g7h8i9j0k1.yaml | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 releasenotes/notes/parsemail-transaction-d4e5f6g7h8i9j0k1.yaml diff --git a/patchwork/management/commands/parsemail.py b/patchwork/management/commands/parsemail.py index bcb257fe9714..2f90047a991b 100644 --- a/patchwork/management/commands/parsemail.py +++ b/patchwork/management/commands/parsemail.py @@ -8,6 +8,7 @@ import logging import sys from django.core.management import base +from django.db import transaction from patchwork.parser import parse_mail from patchwork.parser import DuplicateMailError @@ -57,7 +58,8 @@ class Command(base.BaseCommand): # broken email (ValueError): 1 (this could be noisy, if it's an issue # we could use a different return code) try: - result = parse_mail(mail, options['list_id']) + with transaction.atomic(): + result = parse_mail(mail, options['list_id']) if result is None: logger.warning('Nothing added to database') except DuplicateMailError as exc: diff --git a/releasenotes/notes/parsemail-transaction-d4e5f6g7h8i9j0k1.yaml b/releasenotes/notes/parsemail-transaction-d4e5f6g7h8i9j0k1.yaml new file mode 100644 index 000000000000..37ebb0573906 --- /dev/null +++ b/releasenotes/notes/parsemail-transaction-d4e5f6g7h8i9j0k1.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - | + Wrap the entire parse_mail() function in a single database + transaction to prevent partial state from being visible to + concurrent readers. -- 2.54.0 _______________________________________________ Patchwork mailing list [email protected] https://lists.ozlabs.org/listinfo/patchwork
