Skip to content

Commit b8b9eb6

Browse files
committed
Idea here:
#159 (comment) * created `rqcronjobs` management command * add some tests for it * add some documentation
1 parent 5873bac commit b8b9eb6

File tree

4 files changed

+161
-0
lines changed

4 files changed

+161
-0
lines changed

README.rst

+27
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,33 @@ You can use also use the management command ``rqscheduler`` to start the schedul
167167

168168
python manage.py rqscheduler
169169

170+
Support for RQ Scheduler's cron
171+
-------------------------------
172+
173+
If you have `RQ Scheduler <https://github.com/ui/rq-scheduler>`_ installed,
174+
you can easily manage Your cron entries using ``settings.RQ_CRONJOBS``:
175+
176+
.. code-block:: python
177+
178+
RQ_CRONJOBS = [
179+
('*/10 * * * *', 'whatever.function'),
180+
{
181+
'cron_string': '*/10 * * * *',
182+
'func': 'whatever.function',
183+
'timeout': 50,
184+
'args': ('foo', 'bar'),
185+
'kwargs': {'foo':'bar'},
186+
'queue': 'default',
187+
},
188+
]
189+
190+
Use the management command ``rqcronjobs`` after each deployment to reinstall all
191+
cronjobs in the scheduler::
192+
193+
python manage.py rqcronjobs
194+
195+
Note, that this command will remove all previous jobs in the default scheduler.
196+
170197
Support for django-redis and django-redis-cache
171198
-----------------------------------------------
172199

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# -*- coding: utf-8 -*-
2+
from optparse import make_option
3+
4+
from django.core.management.base import BaseCommand
5+
6+
from django_rq import get_scheduler
7+
from django_rq import settings
8+
9+
10+
class Command(BaseCommand):
11+
help = 'Remove all cronjobs from scheduer and install new ones defined in RQ_CRONJOBS setting (by default). ' \
12+
'See possible options to get more...'
13+
option_list = BaseCommand.option_list + (
14+
make_option(
15+
'-i',
16+
'--install',
17+
action='store_true',
18+
dest='install',
19+
default=False,
20+
help='Limit only to installing cronjobs defined in RQ_CRONJOBS setting.'
21+
),
22+
make_option(
23+
'-r',
24+
'--remove',
25+
action='store_true',
26+
dest='remove',
27+
default=False,
28+
help='Limit only to removing all cronjobs from scheduler.'
29+
),
30+
make_option(
31+
'-l',
32+
'--list',
33+
action='store_true',
34+
dest='list',
35+
default=False,
36+
help='List cronjobs defined in RQ_CRONJOBS setting and defined in scheduler.'
37+
),
38+
)
39+
40+
def handle(self, *args, **options):
41+
scheduler = get_scheduler()
42+
43+
if options.get('list'):
44+
print('Cronjobs from scheduler:')
45+
for cronjob in scheduler.get_jobs():
46+
print('* {}'.format(cronjob))
47+
print('')
48+
print('Cronjobs defined in settings.RQ_CRONJOBS:')
49+
for cronjob_entry in settings.CRONJOBS:
50+
print('* {}'.format(cronjob_entry))
51+
print('')
52+
else:
53+
reinstall = not (options.get('install') or options.get('remove'))
54+
55+
if reinstall or options.get('remove'):
56+
print('Removed cronjobs from scheduler:')
57+
for cronjob in scheduler.get_jobs():
58+
print('* {}'.format(cronjob))
59+
cronjob.delete()
60+
print('')
61+
62+
if reinstall or options.get('install'):
63+
print('Cronjobs installed from settings.RQ_CRONJOBS:')
64+
for cronjob_entry in settings.CRONJOBS:
65+
if type(cronjob_entry) is dict:
66+
args = []
67+
kwargs = cronjob_entry
68+
else:
69+
args = cronjob_entry
70+
kwargs = {}
71+
cronjob = scheduler.cron(
72+
*args, **kwargs
73+
)
74+
print('* {}'.format(cronjob))
75+
print('')

django_rq/settings.py

+8
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from django.conf import settings
44
from django.core.exceptions import ImproperlyConfigured
5+
from django.utils.functional import lazy
56

67
from .queues import get_unique_connection_configs
78

@@ -22,3 +23,10 @@
2223

2324
# Get exception handlers
2425
EXCEPTION_HANDLERS = getattr(settings, 'RQ_EXCEPTION_HANDLERS', [])
26+
27+
28+
# laizly get RQ_CRONJOBS from django settings
29+
# for override_settings support in tests
30+
def get_cronjobs():
31+
return getattr(settings, 'RQ_CRONJOBS', [])
32+
CRONJOBS = lazy(get_cronjobs, list)()

django_rq/tests/tests.py

+51
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from docutils.utils.math.latex2mathml import over
2+
13
from django.contrib.auth.models import User
24
from django.core.management import call_command
35
from django.core.urlresolvers import reverse
@@ -592,3 +594,52 @@ def test_get_queue_django_redis_cache(self):
592594
self.assertEqual(connection_kwargs['port'], int(cachePort))
593595
self.assertEqual(connection_kwargs['db'], int(cacheDBNum))
594596
self.assertEqual(connection_kwargs['password'], None)
597+
598+
599+
class RqcronjobsTest(TestCase):
600+
RQ_CRONJOBS = [
601+
('*/10 * * * *', 'whatever.function'),
602+
{
603+
'cron_string': '*/10 * * * *',
604+
'func': 'whatever.function',
605+
'timeout': 5,
606+
},
607+
]
608+
609+
def setUp(self):
610+
self.scheduler = get_scheduler()
611+
self.clear_scheduler()
612+
613+
def tearDown(self):
614+
self.clear_scheduler()
615+
616+
def clear_scheduler(self):
617+
for scheduled_job in self.scheduler.get_jobs():
618+
scheduled_job.delete()
619+
620+
def add_one_job_to_scheduler(self):
621+
self.scheduler.cron(
622+
*self.RQ_CRONJOBS[0]
623+
)
624+
625+
@skipIf(RQ_SCHEDULER_INSTALLED is False, 'RQ Scheduler not installed')
626+
def test_remove(self):
627+
self.add_one_job_to_scheduler()
628+
self.assertEqual(len(self.scheduler.get_jobs()), 1)
629+
call_command('rqcronjobs', remove=True)
630+
self.assertEqual(len(self.scheduler.get_jobs()), 0)
631+
632+
@skipIf(RQ_SCHEDULER_INSTALLED is False, 'RQ Scheduler not installed')
633+
@override_settings(RQ_CRONJOBS=RQ_CRONJOBS)
634+
def test_install(self):
635+
self.assertEqual(len(self.scheduler.get_jobs()), 0)
636+
call_command('rqcronjobs', install=True)
637+
self.assertEqual(len(self.scheduler.get_jobs()), 2)
638+
639+
@skipIf(RQ_SCHEDULER_INSTALLED is False, 'RQ Scheduler not installed')
640+
@override_settings(RQ_CRONJOBS=RQ_CRONJOBS)
641+
def test_reinstall(self):
642+
self.add_one_job_to_scheduler()
643+
self.assertEqual(len(self.scheduler.get_jobs()), 1)
644+
call_command('rqcronjobs')
645+
self.assertEqual(len(self.scheduler.get_jobs()), 2)

0 commit comments

Comments
 (0)