Skip to content

Commit

Permalink
Merge pull request #10 from Koed00/dev
Browse files Browse the repository at this point in the history
Schedules of type ONCE will selfdestruct with negative repeats
  • Loading branch information
Koed00 committed Jul 12, 2015
2 parents fdfa938 + 6c9dd1a commit ea7115f
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 5 deletions.
11 changes: 9 additions & 2 deletions django_q/cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
27 changes: 26 additions & 1 deletion django_q/tests/test_scheduler.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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,
Expand All @@ -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
4 changes: 3 additions & 1 deletion docs/admin.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
~~~~~~~~

Expand Down
4 changes: 3 additions & 1 deletion docs/schedules.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit ea7115f

Please sign in to comment.