Python每20秒运行一次cron作业

时间:2017-10-11 09:47:14

标签: python cron celery

我总是使用芹菜定期任务来运行cron,但这次芹菜的crontab无法满足我的cronjob。我需要一个只有在20:50到21:10每20秒运行的cron 。似乎无法实现这一目标

2 个答案:

答案 0 :(得分:0)

您可以将python脚本添加到系统的crontab中,也可以自己编写代码。只需启动一个新的线程,计算到星期二20:50之前的时间,然后睡到那时,然后运行工作并在剩余的几秒钟内休息,在21:10之后再次计算到星期二20:50的时间。

使用命令time.time()time.sleep()可以轻松完成此操作。

答案 1 :(得分:0)

如果有人想在几秒钟内启用芹菜的crontab;以下是通过扩展crontab

的示例
from celery.schedules import crontab, cronfield
from celery.utils.timeutils import ffwd

CRON_REPR = '''\
<crontab: {0._orig_second} {0._orig_minute} {0._orig_hour} {0._orig_day_of_week} \
{0._orig_day_of_month} {0._orig_month_of_year} (s/m/h/d/dM/MY)>\
'''

class ExtendedCrontab(crontab):
    '''
    custom crontab to support 'seconds'
    '''

    def __init__(self, second=0, minute='*', hour='*', day_of_week='*',
                 day_of_month='*', month_of_year='*', nowfun=None, app=None):
        super().__init__(second, minute, hour, day_of_week, day_of_month,
                         month_of_year, nowfun, app)
        self._orig_second = cronfield(second)
        self.second = self._expand_cronspec(second, 60)


    def _delta_to_next(self, last_run_at, next_hour, next_minute, next_second):
        '''
        Takes a datetime of last run, next minute and hour, and
        returns a relativedelta for the next scheduled day and time.
        Only called when day_of_month and/or month_of_year cronspec
        is specified to further limit scheduled task execution.
        '''

        _ffwd = super()._delta_to_next(last_run_at, next_hour, next_minute)
        _ffwd.second = next_second
        return _ffwd

    def __repr__(self):
        return CRON_REPR.format(self)

    def __reduce__(self):
        return (self.__class__, (self._orig_second,
                                 self._orig_minute,
                                 self._orig_hour,
                                 self._orig_day_of_week,
                                 self._orig_day_of_month,
                                 self._orig_month_of_year), None)

    def remaining_delta(self, last_run_at, tz=None, ffwd=ffwd):
        tz = tz or self.tz
        last_run_at = self.maybe_make_aware(last_run_at)
        now = self.maybe_make_aware(self.now())
        dow_num = last_run_at.isoweekday() % 7  # Sunday is day 0, not day 7
        execute_this_date = (last_run_at.month in self.month_of_year and
                             last_run_at.day in self.day_of_month and
                             dow_num in self.day_of_week)

        execute_this_hour = (execute_this_date and
                             last_run_at.day == now.day and
                             last_run_at.month == now.month and
                             last_run_at.year == now.year and
                             last_run_at.hour in self.hour and
                             last_run_at.minute < max(self.minute))
        execute_this_minute = (last_run_at.minute in self.minute and
                               last_run_at.second < max(self.second))
        if execute_this_minute:
            next_second = min(second for second in self.second
                              if second > last_run_at.second)
            delta = ffwd(second=next_second, microsecond=0)
        else:
            if execute_this_hour:
                next_minute = min(minute for minute in self.minute
                                  if minute > last_run_at.minute)
                next_second = min(self.second)
                delta = ffwd(minute=next_minute, second=next_second, microsecond=0)
            else:
                next_minute = min(self.minute)
                next_second = min(self.second)
                execute_today = (execute_this_date and
                                 last_run_at.hour < max(self.hour))

                if execute_today:
                    next_hour = min(hour for hour in self.hour
                                    if hour > last_run_at.hour)
                    delta = ffwd(hour=next_hour, minute=next_minute,
                                 second=next_second, microsecond=0)
                else:
                    next_hour = min(self.hour)
                    all_dom_moy = (self._orig_day_of_month == '*' and
                                   self._orig_month_of_year == '*')
                    if all_dom_moy:
                        next_day = min([day for day in self.day_of_week
                                        if day > dow_num] or self.day_of_week)
                        add_week = next_day == dow_num

                        delta = ffwd(weeks=add_week and 1 or 0,
                                     weekday=(next_day - 1) % 7,
                                     hour=next_hour,
                                     minute=next_minute,
                                     second=next_second,
                                     microsecond=0)
                    else:
                        delta = self._delta_to_next(last_run_at,
                                                    next_hour, next_minute,
                                                    next_second)
        return self.to_local(last_run_at), delta, self.to_local(now)

    def __eq__(self, other):
        if isinstance(other, crontab):
            return (other.month_of_year == self.month_of_year and
                    other.day_of_month == self.day_of_month and
                    other.day_of_week == self.day_of_week and
                    other.hour == self.hour and
                    other.minute == self.minute and
                    other.second == self.second)
        return NotImplemented

ExtendedCrontab(second=second,
                minute=minute,
                hour=hour,
                day_of_week=day_of_week,
                day_of_month=day_of_month,
                month_of_year=month_of_year)