Skip to content

Commit

Permalink
Merge pull request #1 from tom-price/seconds_interval_units
Browse files Browse the repository at this point in the history
Seconds interval units
  • Loading branch information
mattjegan committed Mar 6, 2020
2 parents 83cc432 + 70b2928 commit cbd6d13
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 1 deletion.
18 changes: 18 additions & 0 deletions scheduler/migrations/0006_seconds_interval_units.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 2.1.2 on 2018-10-10 01:02

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('scheduler', '0005_added_result_ttl'),
]

operations = [
migrations.AlterField(
model_name='repeatablejob',
name='interval_unit',
field=models.CharField(choices=[('seconds', 'seconds'), ('minutes', 'minutes'), ('hours', 'hours'), ('days', 'days'), ('weeks', 'weeks')], default='hours', max_length=12, verbose_name='interval unit'),
),
]
19 changes: 18 additions & 1 deletion scheduler/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
from model_utils.models import TimeStampedModel


RQ_SCHEDULER_INTERVAL = getattr(settings, "DJANGO_RQ_SCHEDULER_INTERVAL", 60)


@python_2_unicode_compatible
class BaseJob(TimeStampedModel):

Expand Down Expand Up @@ -90,7 +93,7 @@ def delete(self, **kwargs):
super(BaseJob, self).delete(**kwargs)

def scheduler(self):
return django_rq.get_scheduler(self.queue)
return django_rq.get_scheduler(self.queue, interval=RQ_SCHEDULER_INTERVAL)

def is_schedulable(self):
if self.job_id:
Expand Down Expand Up @@ -160,6 +163,20 @@ class RepeatableJob(ScheduledTimeMixin, BaseJob):
)
repeat = models.PositiveIntegerField(_('repeat'), blank=True, null=True)

def clean(self):
super(RepeatableJob, self).clean()
self.clean_interval_unit()

def clean_interval_unit(self):
if RQ_SCHEDULER_INTERVAL > self.interval_seconds():
raise ValidationError({
'interval_unit': ValidationError(
_("Job interval is set lower than {} queue's interval.".format(self.queue)), code='invalid')
})
if self.interval_seconds() % RQ_SCHEDULER_INTERVAL:
raise ValidationError(_("Job interval is not a multiple of rq_scheduler's interval frequency: {}s".format(
RQ_SCHEDULER_INTERVAL)), code='invalid')

def interval_display(self):
return '{} {}'.format(self.interval, self.get_interval_unit_display())

Expand Down
33 changes: 33 additions & 0 deletions scheduler/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,39 @@ class TestRepeatableJob(TestScheduledJob):
JobClass = RepeatableJob
JobClassFactory = RepeatableJobFactory

def test_clean(self):
job = self.JobClass()
job.queue = list(settings.RQ_QUEUES)[0]
job.callable = 'scheduler.tests.test_job'
job.interval = 1
assert job.clean() is None

def test_clean_seconds(self):
job = self.JobClass()
job.queue = list(settings.RQ_QUEUES)[0]
job.callable = 'scheduler.tests.test_job'
job.interval = 60
job.interval_unit = 'seconds'
assert job.clean() is None

def test_clean_too_frequent(self):
job = self.JobClass()
job.queue = list(settings.RQ_QUEUES)[0]
job.callable = 'scheduler.tests.test_job'
job.interval = 30
job.interval_unit = 'seconds'
with self.assertRaises(ValidationError):
job.clean_interval_unit()

def test_clean_not_multiple(self):
job = self.JobClass()
job.queue = list(settings.RQ_QUEUES)[0]
job.callable = 'scheduler.tests.test_job'
job.interval = 121
job.interval_unit = 'seconds'
with self.assertRaises(ValidationError):
job.clean_interval_unit()

def test_interval_seconds_weeks(self):
job = RepeatableJob()
job.interval = 2
Expand Down

0 comments on commit cbd6d13

Please sign in to comment.