enscope/yii2-scheduler

又一个类似Yii2 Cron的调度器

安装: 389

依赖项: 0

建议者: 0

安全: 0

星星: 2

关注者: 1

分支: 1

开放问题: 0

类型:yii2-extension

1.0.4 2018-05-07 13:11 UTC

This package is not auto-updated.

Last update: 2024-09-23 06:25:15 UTC


README

又一个类似Yii2 Cron的扩展,它是因为我觉得需要一些当时没有的东西而创建的。如果你喜欢它,请随意在你的项目中使用它。目前,它已经在生产环境中成功运行了好几个月。

基本用法

ConsoleController 添加到 config.php 中的 controllerMap

'controllerMap' => [
    ...
    'scheduler' => [
        'class' => \enscope\Scheduler\ConsoleController::className(),
        'tasks' => require dirname(__FILE__) . '/schedule.php',
    ],
    ...
],

任务可以来自外部文件或直接在 config.php 中内联。建议将任务外部化,然后 schedule.php 可以像这样

return [
    [
        'schedule' => '0 2 * * 1-5',
        'class' => 'Main\Notifications\ScheduledTask\NotificationsDigestTask',
    ],
    [
        'schedule' => '* * * * *',
        'class' => 'enscope\Scheduler\ScheduledTask\RunActionScheduledTask',
        'action' => 'mailer/send',
        'params' => [
            'quiet' => true,
        ],
    ],
];

此调度器配置包含两个任务,一个是每天凌晨2点运行的任务,另一个是每分钟运行一次的任务。如你所见,你可以引用类,或通过继承 BaseScheduledTask(原则上,任务必须实现 ScheduledTaskInterface,允许定制调度配置,但建议扩展 BaseScheduledTask 并使用默认的CRON-like配置)或调用另一个控制器中的任何可用操作。

任务将按定义的顺序执行,就像在 tasks 数组中一样。

调度器本身应使用CRON或其他任务调度器运行,为了允许最大的粒度,它应该每分钟运行一次。

计划任务配置

计划任务配置紧密遵循CRON-like原则。调度配置字符串是以下顺序的5部分定义

* * * * *
^ ^ ^ ^ ^ day of week (0-6)
| | | | month (1-12)
| | | day of month (1-31)
| | hour (0-23)
| minute (0-59)

你可以使用连字符定义间隔,例如 0 2 * * 1-5 以在工作日的凌晨2点运行任务,你可以使用斜杠定义周期,例如 */5 * * * * 以每五分钟运行一次任务,你可以指定用逗号分隔的多个值,例如 * 6,12,18 * * * 以每小时运行一次任务(除了午夜)。

实现自定义任务

所有计划任务都必须实现 ScheduledTaskInterface,但此接口不提供实际评估任务运行正确时间的方法,并且会在每次运行调度器时运行任务。

此基本接口很简单

interface ScheduledTaskInterface
{
    /**
     * Executes scheduled task, but task must determine, if it will
     * perform the job or not, based on internal scheduling mechanism.
     *
     * @param \DateTime        $time      Time of the scheduler invocation, that may be different
     *                                    from the current time, but all schedules must relate
     *                                    to this time when checking if schedule is satisfied
     * @param bool             $force     If true, task should run regardless of schedule
     *
     * @return bool TRUE, if the task was actually executed
     */
    public function execute(\DateTime $time, $force = false);
}

注释已经说明了一切。要实现计划任务,你需要实现 execute(DateTime, boolean = false) 方法。任务本身与任务调度器没有关联,它应该包含在任务本身中的调度配置。接口的简单性是按设计进行的,以允许更高级的计划任务配置,如果需要的话。对于大多数用例,扩展抽象 BaseScheduledTask 已经足够,它包含一个需要实现的单个抽象方法 scheduledTask()。该类实现了 execute(..) 方法并自动评估 schedule 是否满足条件,只有当条件满足(并且任务不是强制的)时才运行任务。

异常和错误处理

任务可以抛出任何异常,调度器将处理它,在错误输出中报告错误,包括计划任务名称和异常消息。报告错误后,调度器将继续按定义的顺序运行其他任务。如果需要立即终止 Scheduler 的执行,可以使用 TerminateScheduleException,这将迫使 Scheduler 立即终止并显示适当的错误消息。当然,另一个调度器执行将尝试再次运行任务。