Skip to content

Defer Celery send_queued_mail until the request transaction commits - #530

Merged
selwin merged 2 commits into
ui:masterfrom
Steve0x2a:fix/518-celery-on-commit
Aug 30, 2026
Merged

selwin merged 2 commits into
ui:masterfrom
Steve0x2a:fix/518-celery-on-commit

Conversation

@Steve0x2a

Copy link
Copy Markdown
Contributor

Summary

With CELERY_ENABLED=True and Django ATOMIC_REQUESTS=True, email_queued fires inside the still-open request transaction. queued_mail_handler was calling send_queued_mail.delay() immediately, so a Celery worker could run before commit and get_queued() would see zero rows.

This wraps only the Celery send_queued_mail.delay() in django.db.transaction.on_commit inside queued_mail_handler. The no-Celery / Huey path is unchanged.

Credits @javialon26 for reporting the race and proposing on_commit.

Fixes #518

Test plan

  • RED on unmodified master: QueuedMailHandlerCeleryTests.test_send_queued_mail_delay_waits_for_commit fails (delay called inside atomic)
  • GREEN after fix: both new Celery handler tests pass
  • Full suite: django-admin test tests → 151 tests OK (7 skipped)

With CELERY_ENABLED and ATOMIC_REQUESTS, email_queued fired inside the
still-open request transaction and queued_mail_handler called
send_queued_mail.delay() immediately, so the worker could run before
commit and get_queued() saw zero rows.

Wrap only the Celery delay() in transaction.on_commit. Credits
@javialon26 for the diagnosis.

Fixes ui#518
CI installs only [test] extras (no celery). QueuedMailHandlerCeleryTests
asserted send_queued_mail exists after reload, which fails the ImportError
branch in post_office.tasks. Skip the class unless celery can be imported;
keep the on_commit race coverage when it is present.
@selwin
selwin merged commit 86711b1 into ui:master Aug 30, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Queued emails are not found when CELERY_ENABLED and ATOMIC_REQUESTS are used due to premature task dispatch

2 participants