makinacorpus / cron
简单的应用cron API
Requires
- php: >=8.0
- makinacorpus/argument-resolver: ^1.0.7
- psr/log: >= 1.0
Requires (Dev)
- dragonmantank/cron-expression: ^3.3
- makinacorpus/goat-query: >= 3
- phpunit/phpunit: ^9.1
- symfony/config: ^5.4|^6.0
- symfony/console: ^5.4|^6.0
- symfony/dependency-injection: ^5.4|^6.0
- symfony/http-kernel: ^5.4|^6.0
- symfony/yaml: ^5.4|^6.0
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
这是实验性的,应该可以工作。