philippgrashoff / cronforatk
此包的最新版本(5.0.0)没有可用的许可证信息。
5.0.0
2023-10-02 18:55 UTC
Requires (Dev)
- phpstan/phpstan: 1.*
- phpunit/phpunit: 9.5.25
README
此存储库是 atk4/data 的扩展。它使您能够轻松设置和存储许多不同的cron作业的执行。提供从年调度到分钟调度的多种不同的调度选项。这些cron作业的逻辑必须单独实现。
此存储库包含以下类
- BaseCronJob:这是所有真实cron作业的基础。cron作业的实际逻辑在扩展BaseCronJob的类中实现。
- Scheduler:用于持久化每个所需的执行。它包含有关何时执行哪个BaseCronJob子类的信息。
- Executor:此类包含所有决定何时执行哪个Scheduler(以及相应的BaseCronJob子类)的逻辑。**Executor::run()需要由系统cron每分钟执行一次**,以便此存储库正常工作。
- ExecutionLog:在这里记录执行结果。是否记录执行结果可以针对每个Scheduler进行定义。
- CronJobLoader:这是一个小助手。由于所有cron作业都存储为PHP类,此类检查给定目录中可用的BaseCronJob实现。
如何使用
安装
使用此存储库的最简单方法是将其添加到composer.json的require部分
{ "require": { "philippgrashoff/cronforatk": "4.0.*" } }
设置数据库
此包中的两个类需要数据库表:**Scheduler** 和 **ExecutionLog**。您可以使用 Atk4\Data\Schema\Migrator 在数据库中创建这两个表及其外键。
$persistence = new Sql( 'connection_string', 'username', 'password' ); //Setup database $scheduler = new Scheduler($this->db); (new Migrator($scheduler))->create(); $executionLog = new ExecutionLog($this->db); (new Migrator($executionLog))->create()->createForeignKey($executionLog->getReference('scheduler_id'));
示例用法
1) 创建一个扩展BaseCronJob的真实cron作业
class MyCronJob extends BaseCronJob { public static string $name = 'SomeNameForThisCron'; public static string $description = 'SomeDescriptionExplainingWhatThisIsDoing'; public bool $strict = false; public function execute(): void { //do something $someModel = new SomeModel($this->persistence); $someModel->setLimit(100); foreach ($someModel as $entity) { if($this->strict) { $entity->doSomeStrictCheck(); } else { $entity->doSomeOtherCheck(); } //optionally add some output to log $this->executionLog[] = 'SomeModel With ID ' . $entity->getId() . 'checked at ' . (new \DateTime())->format(DATE_ATOM); } } }
2) 添加一个或多个Scheduler来安排cron作业应该执行的时间
注意:您可以使用 atk4\ui 创建一个漂亮的UI来创建和更新scheduler。在以下示例代码中,scheduler仅在数据级别上创建。
//tell the Schedulers where to look for Cronjob implementations. //In real implementations, extend Scheduler to set this once for all Schedulers $pathsToCronJobs = [__DIR__ => 'cronforatk\docs']; //Have our Cronjob executed Daily. $schedulerDaily = new Scheduler($persistence, ['cronFilesPaths' => $pathsToCronJobs]); $schedulerDaily->set('cronjob_class', MyCronJob::class); $schedulerDaily->set('interval', 'DAILY'); $schedulerDaily->set('time_daily', '03:45'); $schedulerDaily->save(); //you could add more schedulers executing the same cronjob in different intervals. // Here, we will add a weekly check sets the "strict" of MyCronJob to true. Like this, cronjobs can be parametrized $schedulerWeekly = new Scheduler($persistence, ['cronFilesPaths' => $pathsToCronJobs]); $schedulerWeekly->set('cronjob_class', MyCronJob::class); $schedulerWeekly->set('interval', 'WEEKLY'); $schedulerWeekly->set('weekday_weekly', 6); //Saturday $schedulerWeekly->set('time_weekly', '01:32'); $schedulerWeekly->set('defaults', ['strict' => true]); $schedulerWeekly->save();
3) 每分钟运行Executor::run()
Executor::run()检查每个分钟需要执行哪些scheduler(以及相应的cron作业)的设置。添加一个简单的脚本,该脚本由系统cron每分钟执行
$executor = new Executor($persistence); $executor->run();
本README中的所有示例代码都可以在 docs
目录中找到。
版本控制
此存储库的版本号与atk4\data版本相对应。因此,4.0.x与atk4\data 4.0.x兼容,依此类推。
待办事项
- 目前,Scheduler中有不同的时间字段:time_yearly、time_monthly、time_weekly和time_daily。这应该被单个时间字段所取代。
- 没有实现锁定(cron作业可能仍在计划中或正在执行时再次由下一个分钟的Executor::run()执行)。这仅是针对每分钟执行的cron作业的问题。
- 目前没有选项在月底的最后一天执行cron作业。这将是一个合理的补充。