Projet

Général

Profil

0001-cron-add-option-to-force-a-specific-job-to-run-34906.patch

Frédéric Péters, 16 juillet 2019 15:27

Télécharger (5,56 ko)

Voir les différences:

Subject: [PATCH] cron: add option to force a specific job to run (#34906)

 tests/test_publisher.py                | 25 +++++++++++++++++++++++
 wcs/formdef.py                         |  1 +
 wcs/qommon/cron.py                     | 28 +++++++++++++++++---------
 wcs/qommon/management/commands/cron.py |  3 ++-
 4 files changed, 46 insertions(+), 11 deletions(-)
tests/test_publisher.py
16 16
from django.http import Http404
17 17
from django.test import override_settings
18 18
from quixote import cleanup
19
from wcs.qommon import get_publisher_class
19 20
from wcs.qommon.http_request import HTTPRequest
21
from wcs.qommon.cron import CronJob
20 22

  
21 23
from utilities import create_temporary_pub
22 24

  
......
214 216
        with mock.patch('wcs.qommon.management.commands.cron.cron_worker') as cron_worker:
215 217
            call_command('cron')
216 218
            assert cron_worker.call_count == 0
219

  
220
    # run a specific job
221
    jobs = []
222
    def job1(pub):
223
        jobs.append('job1')
224
    def job2(pub):
225
        jobs.append('job2')
226
    def job3(pub):
227
        jobs.append('job3')
228

  
229
    @classmethod
230
    def register_test_cronjobs(cls):
231
        cls.register_cronjob(CronJob(job1, days=[10]))
232
        cls.register_cronjob(CronJob(job2, name='job2', days=[10]))
233
        cls.register_cronjob(CronJob(job3, name='job3', days=[10]))
234

  
235
    with mock.patch('wcs.publisher.WcsPublisher.register_cronjobs', register_test_cronjobs):
236
        get_publisher_class().cronjobs = []
237
        call_command('cron', job_name='job1')
238
        assert jobs == []
239
        get_publisher_class().cronjobs = []
240
        call_command('cron', job_name='job2')
241
        assert jobs == ['job2']
wcs/formdef.py
1544 1544
if get_publisher_class():
1545 1545
    # once a month, look for drafts to remove
1546 1546
    get_publisher_class().register_cronjob(CronJob(clean_drafts,
1547
        name='clean_drafts',
1547 1548
        days=[2], hours=[0], minutes=[0]))
wcs/qommon/cron.py
19 19
from django.conf import settings
20 20

  
21 21
class CronJob(object):
22
    name = None
22 23
    hours = None
23 24
    minutes = None
24 25
    weekdays = None
25 26
    days = None
26 27
    function = None
27 28

  
28
    def __init__(self, function, hours=None, minutes=None, weekdays=None, days=None, hourly=False):
29
    def __init__(self, function, name=None, hours=None, minutes=None, weekdays=None, days=None, hourly=False):
29 30
        self.function = function
31
        self.name = name
30 32
        self.hours = hours
31 33
        self.minutes = minutes
32 34
        self.weekdays = weekdays
......
36 38
            # prevents waking up all jobs at the same time on a server farm.
37 39
            self.minutes = [ord(settings.SECRET_KEY[-1]) % 60]
38 40

  
39
def cron_worker(publisher, now):
41
def cron_worker(publisher, now, job_name=None):
40 42
    try:
41 43
        publisher.set_config()
42 44
    except:
......
47 49
        publisher.reindex_sql()
48 50

  
49 51
    for job in publisher.cronjobs:
50
        if job.days and now[2] not in job.days:
51
            continue
52
        if job.weekdays and now[6] not in job.weekdays:
53
            continue
54
        if job.hours and not now[3] in job.hours:
55
            continue
56
        if job.minutes and not now[4] in job.minutes:
57
            continue
52
        if job_name:
53
            # a specific job name is asked, run it whatever
54
            # the current time is.
55
            if job.name != job_name:
56
                continue
57
        else:
58
            if job.days and now[2] not in job.days:
59
                continue
60
            if job.weekdays and now[6] not in job.weekdays:
61
                continue
62
            if job.hours and not now[3] in job.hours:
63
                continue
64
            if job.minutes and not now[4] in job.minutes:
65
                continue
58 66

  
59 67
        class FakeRequest(object):
60 68
            language = publisher.get_site_language()
wcs/qommon/management/commands/cron.py
34 34
        parser.set_defaults(verbosity=0)
35 35
        parser.add_argument('--force-job', dest='force_job', action='store_true',
36 36
            help='Run even if DISABLE_CRON_JOBS is set in settings')
37
        parser.add_argument('--job', dest='job_name', metavar='NAME')
37 38

  
38 39
    def handle(self, verbosity, **options):
39 40
        if getattr(settings, 'DISABLE_CRON_JOBS', False) and not options['force_job']:
......
54 55
                    if verbosity > 1:
55 56
                        print('cron work on %s' % hostname)
56 57
                    publisher.app_dir = os.path.join(app_dir, hostname)
57
                    cron_worker(publisher, now)
58
                    cron_worker(publisher, now, job_name=options.get('job_name'))
58 59
            if verbosity > 2:
59 60
                print('cron end (release lock %s)' % lockfile)
60 61
        except locket.LockError:
61
-