Merge pull request #44 from Koed00/dev

Adds a n-minutes option to the scheduler
This commit is contained in:
Ilan Steemers
2015-08-06 01:40:42 -07:00
12 changed files with 70 additions and 9 deletions
+1 -1
View File
@@ -9,6 +9,6 @@ from .models import Task, Schedule, Success, Failure
from .cluster import Cluster
from .monitor import Stat
VERSION = (0, 4, 6)
VERSION = (0, 5, 0)
default_app_config = 'django_q.apps.DjangoQConfig'
+3 -1
View File
@@ -440,7 +440,9 @@ def scheduler(list_key=Conf.Q_LIST):
# set up the next run time
if not s.schedule_type == s.ONCE:
next_run = arrow.get(s.next_run)
if s.schedule_type == s.HOURLY:
if s.schedule_type == s.MINUTES:
next_run = next_run.replace(minutes=+(s.minutes or 1))
elif s.schedule_type == s.HOURLY:
next_run = next_run.replace(hours=+1)
elif s.schedule_type == s.DAILY:
next_run = next_run.replace(days=+1)
@@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('django_q', '0005_auto_20150718_1506'),
]
operations = [
migrations.AddField(
model_name='schedule',
name='minutes',
field=models.PositiveSmallIntegerField(help_text='Number of minutes for the Minutes type', blank=True, null=True),
),
migrations.AlterField(
model_name='schedule',
name='schedule_type',
field=models.CharField(max_length=1, choices=[('O', 'Once'), ('I', 'Minutes'), ('H', 'Hourly'), ('D', 'Daily'), ('W', 'Weekly'), ('M', 'Monthly'), ('Q', 'Quarterly'), ('Y', 'Yearly')], default='O', verbose_name='Schedule Type'),
),
]
+4
View File
@@ -137,6 +137,7 @@ class Schedule(models.Model):
args = models.TextField(null=True, blank=True, help_text=_("e.g. 1, 2, 'John'"))
kwargs = models.TextField(null=True, blank=True, help_text=_("e.g. x=1, y=2, name='John'"))
ONCE = 'O'
MINUTES = 'I'
HOURLY = 'H'
DAILY = 'D'
WEEKLY = 'W'
@@ -145,6 +146,7 @@ class Schedule(models.Model):
YEARLY = 'Y'
TYPE = (
(ONCE, _('Once')),
(MINUTES, _('Minutes')),
(HOURLY, _('Hourly')),
(DAILY, _('Daily')),
(WEEKLY, _('Weekly')),
@@ -153,6 +155,8 @@ class Schedule(models.Model):
(YEARLY, _('Yearly')),
)
schedule_type = models.CharField(max_length=1, choices=TYPE, default=TYPE[0][0], verbose_name=_('Schedule Type'))
minutes = models.PositiveSmallIntegerField(null=True, blank=True,
help_text=_('Number of minutes for the Minutes type'))
repeats = models.SmallIntegerField(default=-1, verbose_name=_('Repeats'), help_text=_('n = n times, -1 = forever'))
next_run = models.DateTimeField(verbose_name=_('Next Run'), default=timezone.now, null=True)
task = models.CharField(max_length=100, null=True, editable=False)
+2
View File
@@ -66,6 +66,7 @@ def schedule(func, *args, **kwargs):
name = kwargs.pop('name', None)
hook = kwargs.pop('hook', None)
schedule_type = kwargs.pop('schedule_type', Schedule.ONCE)
minutes = kwargs.pop('minutes', None)
repeats = kwargs.pop('repeats', -1)
next_run = kwargs.pop('next_run', timezone.now())
@@ -75,6 +76,7 @@ def schedule(func, *args, **kwargs):
args=args,
kwargs=kwargs,
schedule_type=schedule_type,
minutes=minutes,
repeats=repeats,
next_run=next_run
)
+7
View File
@@ -71,6 +71,13 @@ def test_scheduler(r):
hook='django_q.tests.tasks.result'
)
assert hasattr(always_schedule, 'pk') is True
# Minute schedule
minute_schedule = create_schedule('django_q.tests.tasks.word_multiply',
2,
word='django',
schedule_type=Schedule.MINUTES,
minutes=10)
assert hasattr(minute_schedule, 'pk') is True
# All other types
for t in Schedule.TYPE:
schedule = create_schedule('django_q.tests.tasks.word_multiply',
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

+5 -1
View File
@@ -11,9 +11,11 @@ Successful tasks
----------------
Shows all successfully executed tasks. Meaning they did not encounter any errors during execution.
From here you can look at details of each task or delete them. Use the group column to sort your results by schedule name or group id.
From here you can look at details of each task or delete them. Use the group filter to filter your results by schedule name or group id.
The table is searchable by `name`, `func` and `group`
.. image:: _static/successful.png
Uses the :class:`Success` proxy model.
.. tip::
@@ -36,6 +38,8 @@ Scheduled tasks
Here you can check on the status of your scheduled tasks, create, edit or delete them.
.. image:: _static/scheduled.png
Repeats
~~~~~~~
If you want a schedule to only run a finite amount of times, e.g. every hour for the next 24 hours, you can do that using the :attr:`Schedule.repeats` attribute.
+2 -2
View File
@@ -70,9 +70,9 @@ author = 'Ilan Steemers'
# built documents.
#
# The short X.Y version.
version = '0.4'
version = '0.5'
# The full version, including alpha/beta/rc tags.
release = '0.4.6'
release = '0.5.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
+21 -3
View File
@@ -32,6 +32,14 @@ You can manage them through the :ref:`admin_page` or directly from your code wit
q_options={'timeout': 30},
schedule_type=Schedule.HOURLY)
# Run a schedule every 5 minutes, starting at 6.
import arrow
schedule('math.hypot',
3, 4,
schedule_type=Schedule.MINUTES,
minutes = 5,
next_run = arrow.utcnow().replace(hour=18, minute=0))
Management Commands
-------------------
@@ -55,7 +63,7 @@ If you want to schedule regular Django management commands, you can use the :mod
Reference
---------
.. py:function:: schedule(func, *args, name=None, hook=None, schedule_type='O', repeats=-1, next_run=now() , q_options=None, **kwargs)
.. py:function:: schedule(func, *args, name=None, hook=None, schedule_type='O', minutes=None, repeats=-1, next_run=now() , q_options=None, **kwargs)
Creates a schedule
@@ -63,7 +71,8 @@ Reference
:param args: arguments for the scheduled function.
:param str name: An optional name for your schedule.
:param str hook: optional result hook function. Dotted strings only.
:param str schedule_type: (O)nce, (H)ourly, (D)aily, (W)eekly, (M)onthly, (Q)uarterly, (Y)early or :attr:`Schedule.TYPE`
:param str schedule_type: (O)nce, M(I)nutes, (H)ourly, (D)aily, (W)eekly, (M)onthly, (Q)uarterly, (Y)early or :attr:`Schedule.TYPE`
:param int minutes: Number of minutes for the Minutes type.
:param int repeats: Number of times to repeat schedule. -1=Always, 0=Never, n =n.
:param datetime next_run: Next or first scheduled execution datetime.
:param dict q_options: async options to use for this schedule
@@ -103,9 +112,14 @@ Reference
.. py:attribute:: TYPE
:attr:`ONCE`, :attr:`HOURLY`, :attr:`DAILY`, :attr:`WEEKLY`, :attr:`MONTHLY`, :attr:`QUARTERLY`, :attr:`YEARLY`
:attr:`ONCE`, :attr:`MINUTES`, :attr:`HOURLY`, :attr:`DAILY`, :attr:`WEEKLY`, :attr:`MONTHLY`, :attr:`QUARTERLY`, :attr:`YEARLY`
.. py:attribute:: minutes
The number of minutes the :attr:`MINUTES` schedule should use.
Is ignored for other schedule types.
.. py:attribute:: repeats
Number of times to repeat the schedule. -1=Always, 0=Never, n =n.
@@ -133,6 +147,10 @@ Reference
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:: MINUTES
`'I'` will run every :attr:`minutes` after its first run.
.. py:attribute:: HOURLY
`'H'` the scheduled task will run every hour after its first run.
+1 -1
View File
@@ -26,7 +26,7 @@ class PyTest(Command):
setup(
name='django-q',
version='0.4.6',
version='0.5.0',
author='Ilan Steemers',
author_email='koed00@gmail.com',
keywords='django task queue worker redis multiprocessing',