Lock the Schedule objects to ensure tasks are created once

Tested this with PostgreSQL and MySQL
This commit is contained in:
Martijn Jacobs
2019-08-12 14:28:26 +02:00
parent abaa0ba39b
commit 924ff928b0
+3 -4
View File
@@ -491,7 +491,8 @@ def scheduler(broker=None):
broker = get_broker() broker = get_broker()
db.close_old_connections() db.close_old_connections()
try: try:
for s in Schedule.objects.exclude(repeats=0).filter(next_run__lt=timezone.now()): with db.transaction.atomic():
for s in Schedule.objects.select_for_update().exclude(repeats=0).filter(next_run__lt=timezone.now()):
args = () args = ()
kwargs = {} kwargs = {}
# get args, kwargs and hook # get args, kwargs and hook
@@ -529,9 +530,7 @@ def scheduler(broker=None):
next_run = next_run.shift(years=+1) next_run = next_run.shift(years=+1)
if Conf.CATCH_UP or next_run > arrow.utcnow(): if Conf.CATCH_UP or next_run > arrow.utcnow():
break break
# arrow always returns a tz aware datetime, and we don't want s.next_run = next_run.datetime
# this when we explicitly configured django with USE_TZ=False
s.next_run = next_run.datetime if settings.USE_TZ else next_run.datetime.replace(tzinfo=None)
s.repeats += -1 s.repeats += -1
# send it to the cluster # send it to the cluster
q_options['broker'] = broker q_options['broker'] = broker