creatortsv/scheduler

独立的包,提供脚本执行计划功能

v1.0.1 2023-09-22 11:14 UTC

This package is auto-updated.

Last update: 2024-09-19 01:50:55 UTC


README

CI

独立的包,提供脚本执行计划功能。

安装

composer install creatortsv/scheduler

入门指南

开始使用调度器很简单。

use Creatortsv\Scheduler\Registrar\ScheduleRegistrar;
use Creatortsv\Scheduler\Scheduler;

$job = function (): void {
    /* your job logic here ... */
}

$scheduler = new Scheduler();
$scheduler->getRegistrar()->register($job);
$scheduler->run();

上面的例子只是注册了一个简单的闭包函数作为任务,使用默认的cron表达式* * * * *(这意味着它将每分钟执行一次)并运行它。

Cron表达式

有关Cron表达式对象的完整文档,请访问https://github.com/dragonmantank/cron-expression

每个任务都有自己的cron表达式对象。 ScheduleRegistrarInterfaceregister 方法返回一个默认值为 * * * * * 的cron表达式对象。因此,您可以在任务注册后更改它。

/* Initializing scheduler ... */

$expr = $scheduler->getRegistrar()->register($job);
$expr->setExpression('0 */2 * * *');

/* every two days at 00:00 */

调度提供者

有时您想注册多个可以通过特定逻辑分组的工作。在这种情况下,调度提供者更有用。

use Creatortsv\Scheduler\Provider\ScheduleProviderInterface;
use Creatortsv\Scheduler\Registrar\ScheduleRegistrarInterface;

class MyScheduleProvider implements ScheduleProviderInterface
{
    public function boot(ScheduleRegistrarInterface $registrar): void
    {
        // Register specific jobs here ...
    }
}

不要忘记通过调度对象添加您的提供者

/* Initializing scheduler ... */

$scheduler->add(new MyScheduleProvider());

运行调度器

/* Initializing scheduler ... */

$scheduler->run();

默认情况下,调度器使用每个任务的当前 DateTime 对象运行,这意味着它将创建一个 DateTime 对象和每个Cron表达式对象,使用相同的时间戳来确定是否是执行任务的时间。

但有时您需要在特定的timestamp上运行您的调度,例如测试。使用 Scheduler::at 方法更改默认行为。

/* Initializing scheduler ... */

$date = new DateTime();
$date->modify('-3 days');

$scheduler->at($date)->run();

高级用法

有时您可能想控制除了默认行为之外必须执行哪些任务。例如,当前时刻只能运行已注册任务的唯一实例。

在这种情况下,您可以使用 Scheduler::boot 方法而不是 Scheduler::runboot 方法返回 ScheduleIterator 对象,每个项目都是一个必须由给定timestamp执行的作业实例,每个键是给定作业的cron表达式。

让我们想象一下,您有一个确定作业已经在执行中的服务

class JobManager
{
    public function isReleased(SpecificJobInterface $job): bool
    {
        /* your logic is here ... */
    }
}

因此,您可以使用此服务

/* Initializing $scheduler and your $jobManager ... */

foreach ($scheduler->boot() as $job) {
    if ($job instanceof SpecificJobInterface) {
        $jobManager->isReleased($job) && $job();
    }
}

但这是一种更好的做法

/* Initializing $scheduler and your $jobManager ... */

$scheduler->getModerator()->register($jobManager->isReleased(...));
$scheduler->run();

您不必担心作业是否具有不同类型的可调用对象