Schedules of type ONCE will now self destruct with negative repeats or just deactivated with positive repeats

This commit is contained in:
Ilan Steemers
2015-07-11 11:32:46 +02:00
parent fdfa938113
commit 6c9dd1a910
4 changed files with 41 additions and 5 deletions

View File

@@ -442,14 +442,21 @@ def scheduler(list_key=Conf.Q_LIST):
next_run = next_run.replace(years=+1)
s.next_run = next_run.datetime
s.repeats += -1
else:
s.repeats = 0
# send it to the cluster
kwargs['list_key'] = list_key
s.task = tasks.async(s.func, *args, **kwargs)
# log it
if not s.task:
logger.error(_('{} failed to create a task from schedule {} [{}]').format(current_process().name, s.id),
s.func)
else:
logger.info(_('{} created a task from schedule {} [{}]').format(current_process().name, s.id, s.func))
# default behavior is to delete a ONCE schedule
if s.schedule_type == s.ONCE:
if s.repeats < 0:
s.delete()
return
# but not if it has a positive repeats
s.repeats = 0
# save the schedule
s.save()

View File

@@ -1,6 +1,8 @@
from multiprocessing import Queue, Event, Value
import pytest
import arrow
from django.utils import timezone
from django_q.conf import redis_client
from django_q.cluster import pusher, worker, monitor, scheduler
@@ -45,10 +47,30 @@ def test_scheduler(r):
assert schedule.repeats == 0
assert schedule.last_run() is not None
assert schedule.success() is True
assert schedule.next_run < arrow.get(timezone.now()).replace(hours=+1)
task = fetch(schedule.task)
assert task is not None
assert task.success is True
assert task.result < 0
# Once schedule with delete
once_schedule = create_schedule('django_q.tests.tasks.word_multiply',
2,
word='django',
schedule_type=Schedule.ONCE,
repeats=-1,
hook='django_q.tests.tasks.result'
)
assert hasattr(once_schedule, 'pk') is True
# negative repeats
always_schedule = create_schedule('django_q.tests.tasks.word_multiply',
2,
word='django',
schedule_type=Schedule.DAILY,
repeats=-1,
hook='django_q.tests.tasks.result'
)
assert hasattr(always_schedule, 'pk') is True
# All other types
for t in Schedule.TYPE:
schedule = create_schedule('django_q.tests.tasks.word_multiply',
2,
@@ -59,4 +81,7 @@ def test_scheduler(r):
)
assert schedule is not None
assert schedule.last_run() is None
scheduler()
scheduler(list_key=list_key)
scheduler(list_key=list_key)
# ONCE schedule should be deleted
assert Schedule.objects.filter(pk=once_schedule.pk).exists() is False

View File

@@ -41,12 +41,14 @@ In this case you would set the schedule type to :attr:`Schedule.HOURLY` and the
When you set repeats to `-1` the schedule will continue indefinitely and the repeats will still count down. This can be used as an indicator of how many times the schedule has been executed.
An exception to this are schedules of type :attr:`Schedule.ONCE`. Repeats are ignored by this schedule type and it will always reset it zero after execution.
An exception to this are schedules of type :attr:`Schedule.ONCE`. Negative repeats for this schedule type will cause it to be deleted from the database.
This behavior is useful if you have many delayed actions which you do not necessarily need a result for. A positive number will keep the ONCE schedule, but it will not run again.
.. note::
To run a `Once` schedule again, change the repeats to something other than `0`. Set a new run time before you do this or let it execute immediately.
Next run
~~~~~~~~

View File

@@ -116,7 +116,9 @@ Reference
.. py:attribute:: ONCE
`'O'` the schedule will only run once. Repeats are ignored and set to `0` after execution.
`'O'` the schedule will only run once.
If it has a negative :attr:`repeats` it will be deleted after it has run.
If you want to keep the result, set :attr:`repeats` to a positive number.
.. py:attribute:: HOURLY