调度
Queuety 内置了对周期性任务的支持。调度信息会存储在数据库中,并由长期运行的 wp queuety work 进程(或工作进程池的父进程)大约每分钟评估一次,而无需依赖 wp_cron。wp queuety work --once、wp queuety flush 和插件内置的 WP-Cron 回退机制都不会评估调度(#14);如果没有长期运行的工作进程,请自行运行 wp queuety schedule run。
间隔调度
对于简单的基于间隔的调度,请使用 every()。表达式可以是任何兼容 PHP 的 DateTimeImmutable::modify() 字符串:
use Queuety\Queuety;
Queuety::schedule( 'cleanup_handler' )
->every( '1 hour' )
->on_queue( 'maintenance' );
Queuety::schedule( 'sync_inventory' )
->every( '30 minutes' )
->on_queue( 'sync' );
Queuety::schedule( 'daily_report', [ 'type' => 'summary' ] )
->every( '1 day' );
Cron 调度
使用 cron() 编写标准的 5 字段 cron 表达式:
// Every day at 3am
Queuety::schedule( 'nightly_cleanup' )
->cron( '0 3 * * *' );
// Every Monday at 9am
Queuety::schedule( 'weekly_digest' )
->cron( '0 9 * * 1' )
->on_queue( 'emails' );
// Every 15 minutes
Queuety::schedule( 'health_check' )
->cron( '*/15 * * * *' );
调度选项
PendingSchedule 构建器支持以下方法:
| 方法 | 说明 |
|---|---|
every( string $interval ) |
设置间隔表达式 |
cron( string $expression ) |
设置 cron 表达式 |
on_queue( string $queue ) |
设置目标队列(默认值:'default') |
overlap( OverlapPolicy $policy ) |
设置重叠策略(默认值:Allow) |
调度分发前必须调用 every() 或 cron()。如果两者都未设置,则会抛出 RuntimeException。
重叠策略
当下一个调度周期触发时,如果某个计划任务仍在运行(等待中或处理中),重叠策略会决定后续行为。使用 overlap() 方法设置:
use Queuety\Queuety;
use Queuety\Enums\OverlapPolicy;
Queuety::schedule( 'sync_inventory' )
->every( '5 minutes' )
->overlap( OverlapPolicy::Skip )
->on_queue( 'sync' );
OverlapPolicy 枚举包含三种情况:
| 策略 | 值 | 行为 |
|---|---|---|
OverlapPolicy::Allow |
allow |
始终分发新任务,即使上一次运行仍处于活动状态。这是默认值。 |
OverlapPolicy::Skip |
skip |
如果处理程序有任何等待中或处理中的任务,则跳过当前周期。next_run 会正常更新,以便调度保持原有节奏。 |
OverlapPolicy::Buffer |
buffer |
与 Skip 类似,不分发此周期,且 next_run 会前进到下一个常规触发时间。与 Skip 不同,last_run 不会更新。 |
允许(默认)
同一处理程序的多个实例可以并发运行。适用于幂等处理程序,因为重叠运行不会造成影响。
Queuety::schedule( 'send_heartbeat_ping' )
->every( '1 minute' )
->overlap( OverlapPolicy::Allow );
跳过
如果处理程序仍在运行,则会静默跳过本次周期。适用于运行第二个实例会造成浪费或引发冲突的处理程序。
Queuety::schedule( 'rebuild_search_index' )
->every( '10 minutes' )
->overlap( OverlapPolicy::Skip );
缓冲
目前其行为与 Skip 相同:处理程序仍有等待中或处理中的任务时,不分发本次周期,且 next_run 会前进到下一个常规触发时间。两者唯一的区别是,Buffer 会让 last_run 保持不变,而 Skip 会将被跳过的周期记录为上次运行时间。
Queuety::schedule( 'sync_inventory' )
->every( '5 minutes' )
->overlap( OverlapPolicy::Buffer );
工作原理
创建调度时,Queuety 会将其连同表达式、处理程序、负载和计算出的下次运行时间存储在 queuety_schedules 表中。
每次调度器周期触发时(长期运行的工作进程中大约每分钟一次,或运行 wp queuety schedule run 时),调度器会检查 next_run 已到期的调度。对于每个到期的调度,它都会分发一个新任务,并将 next_run 更新为下次触发时间。
通过 CLI 管理调度
# List all schedules
wp queuety schedule list
# Add a recurring schedule
wp queuety schedule add cleanup_handler --every="1 hour"
wp queuety schedule add nightly_report --cron="0 3 * * *" --queue=reports
# Remove a schedule
wp queuety schedule remove cleanup_handler
# Manually trigger the scheduler
wp queuety schedule run
通过 PHP 管理调度
// Get the scheduler instance
$scheduler = Queuety::scheduler();
// List all schedules
$schedules = $scheduler->list();
// Remove a schedule by handler name
$scheduler->remove( 'cleanup_handler' );
// Manually trigger a tick
$count = $scheduler->tick();
负载
调度可以包含静态负载,并将其传递给每个分发的任务:
Queuety::schedule( 'generate_report', [ 'type' => 'daily', 'format' => 'pdf' ] )
->every( '1 day' )
->on_queue( 'reports' );
每次调度触发时,都会使用此负载分发一个新任务。