Skip to content

Commit afbe6aa

Browse files
fix: queue tasks in on_commit hook (ietf-tools#8149)
* fix: dispatch tasks in on_commit hook * test: fix test
1 parent 7b749f1 commit afbe6aa

3 files changed

Lines changed: 25 additions & 7 deletions

File tree

ietf/community/models.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44

55
from django.conf import settings
6-
from django.db import models
6+
from django.db import models, transaction
77
from django.db.models import signals
88
from django.urls import reverse as urlreverse
99

@@ -117,7 +117,10 @@ def notify_events(sender, instance, **kwargs):
117117
# start a Celery task during tests. To prevent this, don't queue a celery task if we're running
118118
# tests.
119119
if settings.SERVER_MODE != "test":
120-
notify_event_to_subscribers_task.delay(event_id=instance.pk)
120+
# Wrap in on_commit so the delayed task cannot start until the view is done with the DB
121+
transaction.on_commit(
122+
lambda: notify_event_to_subscribers_task.delay(event_id=instance.pk)
123+
)
121124

122125

123126
signals.post_save.connect(notify_events)

ietf/community/tests.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,8 +431,10 @@ def test_subscription_for_group(self):
431431
r = self.client.get(url)
432432
self.assertEqual(r.status_code, 200)
433433

434+
# Mock out the on_commit call so we can tell whether the task was actually queued
435+
@mock.patch("ietf.submit.views.transaction.on_commit", side_effect=lambda x: x())
434436
@mock.patch("ietf.community.models.notify_event_to_subscribers_task")
435-
def test_notification_signal_receiver(self, mock_notify_task):
437+
def test_notification_signal_receiver(self, mock_notify_task, mock_on_commit):
436438
"""Saving a DocEvent should notify subscribers
437439
438440
This implicitly tests that notify_events is hooked up to the post_save signal.

ietf/sync/views.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from django.conf import settings
99
from django.contrib.auth.models import User
1010
from django.contrib.contenttypes.models import ContentType
11+
from django.db import transaction
1112
from django.http import HttpResponse, HttpResponseRedirect, Http404
1213
from django.shortcuts import render
1314
from django.utils import timezone
@@ -79,16 +80,28 @@ def notify(request, org, notification):
7980
if request.method == "POST":
8081
if notification == "index":
8182
log("Queuing RFC Editor index sync from notify view POST")
82-
tasks.rfc_editor_index_update_task.delay()
83+
# Wrap in on_commit so the delayed task cannot start until the view is done with the DB
84+
transaction.on_commit(
85+
lambda: tasks.rfc_editor_index_update_task.delay()
86+
)
8387
elif notification == "queue":
8488
log("Queuing RFC Editor queue sync from notify view POST")
85-
tasks.rfc_editor_queue_updates_task.delay()
89+
# Wrap in on_commit so the delayed task cannot start until the view is done with the DB
90+
transaction.on_commit(
91+
lambda: tasks.rfc_editor_queue_updates_task.delay()
92+
)
8693
elif notification == "changes":
8794
log("Queuing IANA changes sync from notify view POST")
88-
tasks.iana_changes_update_task.delay()
95+
# Wrap in on_commit so the delayed task cannot start until the view is done with the DB
96+
transaction.on_commit(
97+
lambda: tasks.iana_changes_update_task.delay()
98+
)
8999
elif notification == "protocols":
90100
log("Queuing IANA protocols sync from notify view POST")
91-
tasks.iana_protocols_update_task.delay()
101+
# Wrap in on_commit so the delayed task cannot start until the view is done with the DB
102+
transaction.on_commit(
103+
lambda: tasks.iana_protocols_update_task.delay()
104+
)
92105

93106
return HttpResponse("OK", content_type="text/plain; charset=%s"%settings.DEFAULT_CHARSET)
94107

0 commit comments

Comments
 (0)