Skip to content

Commit

Permalink
Proposed handling of intervals in seconds.
Browse files Browse the repository at this point in the history
Rejects when a job's interval is lower than a queue's interval.
Rejects when a job's interval is not a multiple of a queue's interval. This seemed to be the most restrictive approach from which things can be loosened up.
Added a settings parameter DJANGO_RQ_SCHEDULER_INTERVAL that can be used to change the schedular interval. Default is 60 matching DJANGO_RQ's default.
Renamed migration adding seconds to be more descriptive.
  • Loading branch information
tom-price committed May 26, 2019
1 parent 5506b97 commit 70b2928
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 1 deletion.
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 70b2928

Please sign in to comment.