【问题标题】:Is it possible to schedule same task at different cron in celery without duplicating entry是否可以在 celery 的不同 cron 中安排相同的任务而不重复输入
【发布时间】:2019-11-28 10:18:21
【问题描述】:

我想在可能的随机日期以及每个月的最后一天安排 celery 任务。是否可以以某种方式存储 celery 任务的时间表,该任务在月中和月的最后一天都被拾取。一个月的最后一天当然不是一成不变的。是否可以为单个任务存储两个不同的 cron 表达式。正如许多网站所建议的那样,我上个月用 L 尝试了一个 cron 表达式。但它似乎不是一个标准。

【问题讨论】:

  • 我认为在节拍配置中没有两个不同的条目是不可能的...
  • 如果没有重复的任务条目,我绝对不能让任务以 2 个不同的计划运行。对吗?

标签: cron celery cron-task celerybeat


【解决方案1】:

我认为它不支持开箱即用,但编写自定义时间表看起来相当可行。 Celery 支持 crontabsolar 调度,它们是 Python 类,所以我假设可以创建自己的。

我没有测试过,但看起来应该是这样的:

import calendar
import datetime

from celery.schedules import BaseSchedule, schedstate

class last_day_month(BaseSchedule):

    def is_due(self, last_run_at):
        """Return tuple of ``(is_due, next_time_to_run)``.

        Note:
            next time to run is in seconds.

        See Also:
            :meth:`celery.schedules.schedule.is_due` for more information.
        """
        # Same as the one from crontab schedule class
        rem_delta = self.remaining_estimate(last_run_at)
        rem = max(rem_delta.total_seconds(), 0)
        due = rem == 0
        if due:
            rem_delta = self.remaining_estimate(self.now())
            rem = max(rem_delta.total_seconds(), 0)
        return schedstate(due, rem)

    def remaining_estimate(self, last_run_at):
        """Estimate of next run time.

        Returns when the periodic task should run next as a
        :class:`~datetime.timedelta`.
        """
        last_run_at = self.maybe_make_aware(last_run_at)
        now = self.maybe_make_aware(self.now())
        if last_run_at.month == now.month:
            # Already run this month: next time is next month
            month = now.month + 1 if now.month < 12 else 1
            year = now.year + 1 if now.month < 12 else 1
        else:
            # Otherwise, should run this month next
            month, year = now.month, now.year
        # We've got the month and year, now get the last day
        _first_day, last_day = calendar.monthrange(year, month)
        # Build the datetime for next run
        next_utc = self.maybe_make_aware(
            datetime.datetime(year=year, month=month, day=last_day)
        )
        # Return the timedelta from now
        return next_utc - now

这是用来代替 Celery 日程表中的 crontab 课程

【讨论】:

    猜你喜欢
    • 2020-01-09
    • 1970-01-01
    • 1970-01-01
    • 2022-08-14
    • 2020-03-12
    • 1970-01-01
    • 2018-02-26
    • 1970-01-01
    • 2012-05-26
    相关资源
    最近更新 更多