简单的应用cron API

1.0.1 2023-05-22 13:39 UTC

This package is auto-updated.

Last update: 2024-09-08 16:16:56 UTC


README

简单的应用cron任务实现。

工作原理

  • 作为库用户,您可以使用描述性属性将可调用项注册为cron任务。

  • 可以是任何可调用项,一个函数、匿名函数、实例方法、类静态方法或可调用的类实例。

  • 您需要根据您的框架设置系统cron条目以运行应用cron,例如使用Symfony,提供了一个CLI命令。这个检查必须非常频繁地运行,例如每分钟运行一次。

  • 当cron运行时,它会针对每个已注册的任务,检查其计划与当前系统日期的匹配情况。

  • 对于每个匹配的计划,它首先检查两次运行之间的配置最小延迟,并排除最近已经运行的任务。

  • 对于每个剩余的非排除任务,它会运行它,并存储最新的运行数据,如果发生任何错误,还会存储错误消息和错误跟踪。

简单来说,它接受一个任务列表,测试每个任务计划与当前日期的匹配情况,并在匹配时运行它。

默认情况下,状态在运行时保存在内存中,然后丢弃。未来的实现将允许您在PDO和其他后端中存储它。

当状态持久化时,用户可以更改任务计划而无需更改代码。计划始终以原始字符串形式存储,这允许存在替代实现。

默认的计划实现接受不完整的POSIX cron表达式,但仅限于单个数字值。替代实现可以使用dragonmantank/cron-expression来使用更完整的POSIX cron表达式。

路线图

  • makinacorpus/goat-query状态存储实现,
  • PDO状态存储实现,
  • 单元测试Symfony集成,
  • 使用psr/log进行日志记录,无处不在,
  • 添加使用dragonmantank/cron-expression的调度器实现,
  • 提供cron任务列表和详细信息的命令,
  • 通过控制台命令显示有意义的信息。

如何使用

首先,安装它

composer require makinacorpus/cron

然后进行以下操作之一。

独立

配置cron任务

首先,创建一些cron方法

namespace MyVendor\MyApp\Cron;

use MakinaCorpus\Cron\CronTask;

// Using a function.
#[CronTask(id: 'foo', schedule: '1 2 3 4 5')]
function foo(): void
{
    // Do something.
}

// Using an invokable class.
#[CronTask(id: 'bar', schedule: '@daily')]
class Bar
{
    public function __invoke(): mixed
    {
        // Do something.
    }
}

// Using an instance method.
class Buzz
{
    #[CronTask(id: 'buzz', schedule: '@monthly')]
    public function someMethod(): void
    {
    }
}

// Using a static class method.
class Fizz
{
    #[CronTask(id: 'fizz', schedule: '@weekly')]
    public function someMethod(): void
    {
    }
}

然后创建一个任务注册表

namespace MyVendor\MyApp\Command;

use MakinaCorpus\Cron\TaskRegistry\ArrayTaskRegistry;
use MyVendor\MyApp\Cron\Bar;
use MyVendor\MyApp\Cron\Buzz;
use MyVendor\MyApp\Cron\Fizz;

$taskRegistry = new ArrayTaskRegistry([
    'MyVendor\\MyApp\\Cron\\foo',
    new Bar(),
    [new Buzz(), 'someMethod']
    [Fizz::class, 'someMethod'],
]);

运行它

然后,创建一个运行器并执行它,这基本上是您需要在CLI脚本中执行的cron代码。

namespace MyVendor\MyApp\Command;

use MakinaCorpus\Cron\CronRunner;

// $taskRegistry is the instance you created upper.

$runner = new CronRunner($taskRegistry);
$runner->run();

就这样。

默认情况下,计划是宽容的,您可能只需每2或3分钟运行此脚本一次,cron规则将在到期日期后的5分钟时间范围内匹配,以避免错过运行它们。

Symfony

安装

首先将捆绑包添加到config/bundles.php文件中

return [
    // Other bundles.
    MakinaCorpus\Cron\Bridge\Symfony\CronBundle::class => ['all' => true],
];

配置cron任务

创建一些具有cron任务方法的服务,这可以是任何类或服务,唯一的要求是设置目标方法的CronTask属性。

namespace MyVendor\MyApp\Cron;

use MakinaCorpus\Cron\CronTask;

// Using an instance method.
class SomeClassWithCronTaskMethods
{
    #[CronTask(id: 'buzz', schedule: '@monthly')]
    public function someInstanceMethod(): void
    {
    }

    #[CronTask(id: 'buzz', schedule: '@monthly')]
    public static function someStaticMethod(): void
    {
    }
}

使用makinacorpus/argument-resolver依赖项,假设您已安装和配置了提供的捆绑包,您的方 法可以具有其他服务作为参数,它们将在运行时注入。

确保它们在config/services.yaml中或通过其他服务注册方法注册为服务

services:
    MyVendor\MyApp\Cron\SomeClassWithCronTaskMethods:
        autoconfigure: true

就这样。

用法

配置计划实现

默认实现

如果配置保持不变,则默认实现支持不完整的POSIX cron表达式,其中部分只能为单个数字。

对于许多应用程序,这已经足够了。

默认情况下不需要配置,因为这已经是默认的。

dragonmantank/cron-expression

首先安装它

composer require dragonmantank/cron-expression

然后,在您的应用程序引导过程中,调用

use MakinaCorpus\Cron\ScheduleFactoryRegistry;
use MakinaCorpus\Cron\Schedule\CronExpressionScheduleFactory;

ScheduleFactoryRegistry::set(new CronExpressionScheduleFactory());

像平时一样使用此API。

命令

当将其作为Symfony组件使用时,可使用这些命令,但没有任何阻止您在Symfony全栈框架之外设置和使用这些命令。

运行所有cron任务(应该每分钟运行一次的任务)

在您的系统cron、supervisord或其他任何编排应用程序中设置此命令

crontab -e

# Run every minute
* * * * * /symfony/project/path/bin/console cron:run

您也可以手动运行它

bin/console cron:run

强制运行单个cron任务

只需调用相同的命令,将cron任务标识符作为第一个参数添加即可

bin/console cron:run my_cron_task_id

任务配置

设置最小间隔

告诉我。

运行测试

核心测试

简单地运行PHPUnit

composer install
vendor/bin/phpunit

由于缺少配置,数据库相关测试将被跳过。

数据库相关测试

这使用docker compose来启动数据库环境

cd sys/
./run-test.sh

这是实验性的,应该可以工作。