跳转到正文

调度

Queuety 内置了对周期性任务的支持。调度信息会存储在数据库中,并由长期运行的 wp queuety work 进程(或工作进程池的父进程)大约每分钟评估一次,而无需依赖 wp_cron。wp queuety work --once、wp queuety flush 和插件内置的 WP-Cron 回退机制都不会评估调度(#14);如果没有长期运行的工作进程,请自行运行 wp queuety schedule run。

间隔调度

对于简单的基于间隔的调度,请使用 every()。表达式可以是任何兼容 PHP 的 DateTimeImmutable::modify() 字符串:

PHP
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 表达式:

PHP
// 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() 方法设置:

PHP
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 不会更新。

允许(默认)

同一处理程序的多个实例可以并发运行。适用于幂等处理程序,因为重叠运行不会造成影响。

PHP
Queuety::schedule( 'send_heartbeat_ping' )
    ->every( '1 minute' )
    ->overlap( OverlapPolicy::Allow );

跳过

如果处理程序仍在运行,则会静默跳过本次周期。适用于运行第二个实例会造成浪费或引发冲突的处理程序。

PHP
Queuety::schedule( 'rebuild_search_index' )
    ->every( '10 minutes' )
    ->overlap( OverlapPolicy::Skip );

缓冲

目前其行为与 Skip 相同:处理程序仍有等待中或处理中的任务时,不分发本次周期,且 next_run 会前进到下一个常规触发时间。两者唯一的区别是,Buffer 会让 last_run 保持不变,而 Skip 会将被跳过的周期记录为上次运行时间。

PHP
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 管理调度

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();

负载

调度可以包含静态负载,并将其传递给每个分发的任务:

PHP
Queuety::schedule( 'generate_report', [ 'type' => 'daily', 'format' => 'pdf' ] )
    ->every( '1 day' )
    ->on_queue( 'reports' );

每次调度触发时,都会使用此负载分发一个新任务。