PHP API
Queuety 中的所有功能都可通过 Queuety\Queuety 静态类访问。它是派发作业、构建工作流、驱动状态机、管理队列以及访问内部子系统的统一入口。
use Queuety\Queuety;
独立访问核心功能
Queuety 的数据库支持运行时可在 WordPress 之外初始化。
这条独立运行路径适用于编排核心:
- 作业和工作器(工作器池还需要
DB_HOST、DB_NAME、DB_USER和DB_PASSWORD常量,见下文) - 工作流和信号
- 状态机和事件
- 工件、日志、指标和计划
它不能替代 WordPress 适配器。Queuety::on_action()、
replace_wp_cron()、插件引导程序以及真正的 wp queuety ...
注册流程仍需要 WordPress。
Queuety::init( Connection $conn )
使用直接连接数据库的方式初始化 Queuety。
use Queuety\Connection;
use Queuety\Queuety;
$conn = new Connection(
host: '127.0.0.1:3306',
dbname: 'wordpress',
user: 'root',
password: 'secret',
prefix: 'wp_',
);
Queuety::init( $conn );
可选的 table_prefix 参数会按连接更改运行时
表名中的 Queuety 部分:
$conn = new Connection(
host: '127.0.0.1:3306',
dbname: 'wordpress',
user: 'root',
password: 'secret',
prefix: 'wp_',
table_prefix: 'themequeue_',
);
这会将诸如 queuety_jobs 的表解析为 wp_themequeue_jobs。
Queuety::ensure_schema()
确保当前连接对应的 Queuety 运行时表已存在。
Queuety::init( $conn );
Queuety::ensure_schema();
有关完整模型和 WordPress 边界,请参阅 独立使用。
作业
Queuety::dispatch( $handler, $payload )
派发作业。接受处理程序名称字符串或 Contracts\Job 实例。返回 PendingJob 构建器,以便链式设置选项。
// Handler name + payload (original API)
Queuety::dispatch( 'send_email', [ 'to' => 'user@example.com' ] );
// Contracts\Job instance (v0.6.0+)
Queuety::dispatch( new SendEmailJob( to: 'user@example.com' ) );
// With options
Queuety::dispatch( 'send_email', [ 'to' => 'user@example.com' ] )
->on_queue( 'emails' )
->with_priority( Priority::High )
->delay( 300 )
->max_attempts( 5 )
->rate_limit( 10, 60 )
->unique()
->after( $other_job_id );
// Get the job ID
$job_id = Queuety::dispatch( 'send_email', $payload )->id();
传入 Contracts\Job 实例时,序列化器会提取其 FQCN 作为处理程序名称,并将公共属性作为负载。当 $handler 是 Job 实例时,$payload 参数会被忽略。
PendingJob 方法
| 方法 | 说明 |
|---|---|
on_queue( string $queue ) |
设置目标队列 |
with_priority( Priority $priority ) |
设置优先级 |
delay( int $seconds ) |
设置作业可用前的延迟时间 |
max_attempts( int $max ) |
最大重试次数 |
rate_limit( int $max, int $window ) |
速率限制:每个时间窗口内的最大执行次数 |
unique() |
防止重复派发 |
after( int $job_id ) |
等待另一个作业先完成 |
concurrency_group( string $group, int $limit ) |
将作业加入共享工作器准入组 |
cost_units( int $units ) |
为派发附加相对执行成本元数据 |
id() |
强制派发并返回作业 ID |
concurrency_group() 和 cost_units() 属于更广泛的资源管理模型,因此同一次派发可参与基于数量的并发限制、加权队列或提供方预算,以及工作器准入策略。
Queuety::dispatch_sync( $handler, $payload )
在当前进程中同步执行作业,不将其加入队列。
// With a Job instance
Queuety::dispatch_sync( new SendEmailJob( to: 'user@example.com', subject: 'Hi', body: 'Hello' ) );
// With a handler name and payload
Queuety::dispatch_sync( 'send_email', [ 'to' => 'user@example.com' ] );
会直接调用作业的 handle() 方法。不会创建数据库行,也不会使用工作器,且不会应用中间件。
Queuety::batch( $jobs )
通过一条多行 INSERT 派发多个作业。
$job_ids = Queuety::batch( [
[ 'handler' => 'send_email', 'payload' => [ 'to' => 'a@example.com' ], 'queue' => 'emails' ],
[ 'handler' => 'send_email', 'payload' => [ 'to' => 'b@example.com' ], 'priority' => 2 ],
] );
Queuety::create_batch( $jobs )
创建 BatchBuilder,用于派发一组作业并跟踪回调和进度。完整详情请参阅批处理。
$batch = Queuety::create_batch( [
new ImportUsersJob( $chunk_1 ),
new ImportUsersJob( $chunk_2 ),
] )
->name( 'Import users' )
->then( ImportCompleteHandler::class )
->catch( ImportFailedHandler::class )
->finally( ImportCleanupHandler::class )
->allow_failures()
->on_queue( 'imports' )
->dispatch();
BatchBuilder 方法
| 方法 | 返回值 | 说明 |
|---|---|---|
name( string $name ) |
self |
设置批次名称 |
on_queue( string $queue ) |
self |
设置批次中所有作业的队列 |
then( string $handler_class ) |
self |
批次成功完成时调用的处理程序 |
catch( string $handler_class ) |
self |
批次中的首个作业失败时调用的处理程序 |
finally( string $handler_class ) |
self |
批次结束时调用的处理程序(成功或失败) |
allow_failures() |
self |
即使存在失败,也允许触发 then 回调 |
dispatch() |
Batch |
创建批次行和所有作业,并返回 Batch 值对象 |
Queuety::find_batch( $id )
按 ID 查找批次。返回 Batch 值对象或 null。
$batch = Queuety::find_batch( $batch_id );
if ( null !== $batch ) {
echo $batch->progress() . '% complete';
}
工作器控制
Queuety::run_worker( $queue = 'default', $once = false )
直接运行一个工作器循环。
Queuety::run_worker( 'default' );
Queuety::run_worker( 'critical,default', true );
Queuety::run_worker_pool( $workers, $queue = 'default' )
直接运行固定大小的工作器池。需要 pcntl 和 posix 扩展。工作器池会读取 WordPress、DB_HOST、DB_NAME、DB_USER 和 DB_PASSWORD 常量来创建子连接(仅表前缀取自已初始化的连接),因此在 WordPress 之外运行工作器池时,请定义这些常量(#5)。
Queuety::run_worker_pool( 4, 'providers' );
Queuety::run_auto_scaling_worker_pool( $min_workers, $max_workers, $queue = 'default' )
直接运行自适应工作器池。要求与 run_worker_pool() 相同。
Queuety::run_auto_scaling_worker_pool( 2, 6, 'providers' );
Batch 值对象
| 方法/属性 | 类型 | 说明 |
|---|---|---|
$id |
int |
批次 ID |
$name |
string|null |
可选的批次名称 |
$total_jobs |
int |
批次中的作业总数 |
$pending_jobs |
int |
仍待处理的作业数 |
$failed_jobs |
int |
失败的作业数 |
$failed_job_ids |
array |
失败作业的 ID |
$created_at |
DateTimeImmutable |
批次创建时间 |
$finished_at |
DateTimeImmutable|null |
批次完成时间 |
$cancelled_at |
DateTimeImmutable|null |
批次取消时间 |
progress() |
int |
完成百分比(0-100) |
finished() |
bool |
批次是否已完成 |
has_failures() |
bool |
是否有作业失败 |
cancelled() |
bool |
批次是否已取消 |
Queuety::chain( $jobs )
创建 ChainBuilder 以便按顺序执行作业。每个作业都依赖前一个作业成功完成。
$first_job_id = Queuety::chain( [
new FetchDataJob( $url ),
new ProcessDataJob(),
new NotifyCompleteJob(),
] )
->on_queue( 'pipeline' )
->catch( ChainFailedHandler::class )
->dispatch();
ChainBuilder 方法
| 方法 | 返回值 | 说明 |
|---|---|---|
on_queue( string $queue ) |
self |
设置链中所有作业的队列 |
catch( string $handler_class ) |
self |
链中的作业被永久埋藏时调用的处理程序 |
dispatch() |
int |
创建所有作业并设置顺序依赖关系,返回首个作业 ID |
Queuety::retry( $job_id )
重试指定作业。将其状态重置为 pending。
Queuety::retry( 42 );
Queuety::retry_buried()
重试所有已埋藏的作业。返回已重试的作业数。
$count = Queuety::retry_buried();
Queuety::purge( $older_than_days )
清除已完成的作业。返回已清除的作业数。
$count = Queuety::purge(); // uses QUEUETY_RETENTION_DAYS
$count = Queuety::purge( 30 ); // purge jobs older than 30 days
队列
Queuety::stats( $queue )
按状态分组获取作业数量。
$stats = Queuety::stats(); // all queues
$stats = Queuety::stats( 'emails' ); // specific queue
// ['pending' => 12, 'processing' => 3, 'completed' => 150, 'failed' => 2, 'buried' => 1]
Queuety::buried( $queue )
获取所有已埋藏的作业。
$jobs = Queuety::buried();
$jobs = Queuety::buried( 'emails' );
Queuety::pause( $queue )
暂停队列,使工作器跳过该队列。
Queuety::pause( 'emails' );
Queuety::resume( $queue )
恢复已暂停的队列。
Queuety::resume( 'emails' );
Queuety::is_paused( $queue )
检查队列是否已暂停。
if ( Queuety::is_paused( 'emails' ) ) {
// Queue is paused
}
工作流
Queuety::workflow( $name )
开始构建工作流。返回 WorkflowBuilder。
$workflow_id = Queuety::workflow( 'generate_report' )
->then( FetchDataHandler::class )
->then( CallLLMHandler::class )
->then( FormatOutputHandler::class )
->dispatch( [ 'user_id' => 42 ] );
WorkflowBuilder 方法
| 方法 | 说明 |
|---|---|
then( string $handler_class, ?string $name = null ) |
添加顺序步骤。可选名称可用于条件分支。 |
parallel( array $handler_classes ) |
添加并行步骤组。 |
for_each( string $items_key, string $handler_class, ?string $result_key = null, ForEachMode $mode = ForEachMode::All, ?int $quorum = null, ?string $reducer_class = null, ?string $name = null ) |
添加动态 for-each 步骤,根据工作流状态中的每个项目扩展一个分支作业。 |
repeat_while( string $target_step, ?string $state_key = null, mixed $expected = true, ?string $name = null, ?string $condition_class = null, ?int $max_iterations = null ) |
当公共状态键或 RepeatCondition 类匹配时,跳回较早的命名步骤。 |
repeat_until( string $target_step, ?string $state_key = null, mixed $expected = true, ?string $name = null, ?string $condition_class = null, ?int $max_iterations = null ) |
直到公共状态键或 RepeatCondition 类匹配时,跳回较早的命名步骤。 |
run_workflow( string $workflow_name, WorkflowBuilder $sub_builder ) |
添加运行工作流步骤。 |
delay( int $seconds = 0, int $minutes = 0, int $hours = 0, int $days = 0 ) |
添加持久延迟步骤。所有时长会累加。 |
wait_for_signal( string $name, ?string $result_key = null, ?string $step_name = null, array $match_payload = [], ?string $correlation_key = null ) |
添加等待信号步骤。可选的 match_payload 和 correlation_key 可让你忽略无关事件。 |
wait_for_signals( array $signal_names, WaitMode $mode = WaitMode::All, ?string $result_key = null, ?string $name = null, array $match_payload = [], ?string $correlation_key = null ) |
等待多个信号中的全部或任意一个,可选匹配负载和关联信息。 |
wait_for_approval( string $signal_name = 'approval', ?string $result_key = 'approval', ?string $name = null, array $match_payload = [], ?string $correlation_key = null ) |
等待人工批准信号。 |
wait_for_decision( string $approve_signal = 'approved', string $reject_signal = 'rejected', ?string $result_key = 'decision', ?string $name = null, array $match_payload = [], ?string $correlation_key = null ) |
等待批准或拒绝,并存储结构化决策负载。 |
wait_for_input( string $signal_name = 'input', ?string $result_key = 'input', ?string $name = null, array $match_payload = [], ?string $correlation_key = null ) |
等待人工输入信号。 |
wait_for_workflow( int|string $workflow, ?string $result_key = null, ?string $name = null ) |
等待一个工作流 ID,或公共状态中存储的工作流 ID,完成。 |
wait_for_workflows( array|string $workflows, WaitMode $mode = WaitMode::All, ?string $result_key = null, ?string $name = null, ?int $quorum = null ) |
等待多个工作流全部完成、任意一个完成或达到法定数量。 |
wait_for_workflow_group( string $group_key, WaitMode $mode = WaitMode::All, ?int $quorum = null, ?string $result_key = null, ?string $name = null ) |
按内部组键等待先前启动的工作流组。 |
start_workflows( string $items_key, WorkflowBuilder $workflow_builder, string $result_key = 'started_workflow_ids', string $payload_key = 'item', bool $inherit_state = true, ?string $name = null, ?string $group_key = null ) |
为每个运行时项目派发一个顶层工作流,也可使用持久组键标记已启动的工作流集合。 |
start_agents( string $items_key, WorkflowBuilder $workflow_builder, string $result_key = 'agent_workflow_ids', string $payload_key = 'agent_task', bool $inherit_state = true, ?string $name = null, ?string $group_key = null ) |
面向代理的 start_workflows() 别名。 |
wait_for_agents( array|string $workflows = 'agent_workflow_ids', WaitMode $mode = WaitMode::All, ?string $result_key = 'agent_results', ?string $name = null, ?int $quorum = null ) |
面向代理的 wait_for_workflows() 别名。 |
wait_for_agent_group( string $group_key = 'agents', WaitMode $mode = WaitMode::All, ?int $quorum = null, ?string $result_key = 'agent_results', ?string $name = null ) |
面向代理的 wait_for_workflow_group() 别名。 |
version( string $version ) |
为工作流定义标记应用级版本,以便检查和导出。 |
idempotency_key( string $key ) |
使用调用方提供的键使工作流派发持久化。使用相同键再次派发时会返回原工作流 ID。 |
max_transitions( int $max ) |
如果完成的步骤转换超过 $max,则使工作流失败。 |
max_for_each_items( int $max ) |
如果 for_each() 步骤尝试展开超过 $max 个项目,则使工作流失败。 |
max_state_bytes( int $bytes ) |
如果公共状态超过 $bytes,则使工作流失败。 |
max_cost_units( int $max ) |
如果已完成步骤消耗的成本单位超过 $max,则使工作流失败。 |
max_started_workflows( int $max ) |
如果要派发的子工作流超过 $max,则使工作流失败。 |
compensate_with( string $handler_class ) |
为最近添加的步骤附加补偿处理程序。 |
compensate_on_failure() |
工作流失败时自动运行已完成步骤的补偿操作。 |
on_queue( string $queue ) |
设置所有步骤使用的队列。 |
with_priority( Priority $priority ) |
设置所有步骤的优先级。 |
max_attempts( int $max ) |
设置每个步骤的最大重试次数。 |
on_cancel( string $handler_class ) |
注册用于取消操作的清理处理程序类。参阅取消。 |
prune_state_after( int $steps = 2 ) |
启用自动状态裁剪。移除早于阈值的步骤输出。参阅状态裁剪。 |
must_complete_within( int $seconds = 0, int $minutes = 0, int $hours = 0, int $days = 0 ) |
设置工作流的截止时间。所有时长会累加。参阅截止时间。 |
on_deadline( string $handler_class ) |
注册工作流超过截止时间时调用的处理程序。参阅截止时间。 |
dispatch( array $initial_payload = [] ) |
派发工作流。返回工作流 ID。 |
Queuety::workflow_status( $workflow_id )
获取工作流状态。返回 WorkflowState 对象或 null。
$state = Queuety::workflow_status( $workflow_id );
echo $state->name; // 'generate_report'
echo $state->status->value; // 'running'
echo $state->current_step; // 1
echo $state->total_steps; // 3
print_r( $state->state ); // accumulated public state array
echo $state->wait_type; // 'signal' or 'workflow' while blocked
echo $state->wait_mode; // 'all', 'any', or 'quorum'
echo $state->definition_version; // 'research.v2'
echo $state->definition_hash; // '4c7a...'
echo $state->idempotency_key; // 'brief:42:research'
echo $state->artifact_count; // 2
print_r( $state->budget ); // configured workflow budget + current usage
print_r( $state->wait_details ); // matched/remaining blockers, result key, correlation info
print_r( $state->artifact_keys ); // ['draft', 'citations']
WorkflowState 还公开了以下内容:
waiting_for:当前阻止运行的信号名称或工作流 IDcurrent_step_name:当前步骤配置的名称(如有)wait_mode:阻塞期间的当前等待模式(all、any或quorum)wait_details:额外的检查数据,例如匹配的阻塞项与剩余阻塞项definition_version:由version()设置的值(如有)definition_hash:工作流定义的确定性哈希值idempotency_key:持久化调度键(如有)budget:配置的限制及当前用量(启用保护措施时)artifact_count:工作流存储的工件数量artifact_keys:存储的工件键,便于快速检查
Queuety::retry_workflow( $workflow_id )
从失败的步骤重试失败的工作流。
Queuety::retry_workflow( $workflow_id );
如果工作流在失败后已执行补偿,则抛出 RuntimeException。
Queuety::pause_workflow( $workflow_id )
暂停正在运行的工作流。当前步骤已排队的工作仍可能完成,但在恢复工作流之前,不会将后续步骤加入队列。
Queuety::pause_workflow( $workflow_id );
Queuety::resume_workflow( $workflow_id )
恢复已暂停的工作流。
Queuety::resume_workflow( $workflow_id );
Queuety::cancel_workflow( $workflow_id )
取消工作流并运行所有已注册的清理处理程序。将状态设为 cancelled,并将该工作流所有待处理和正在处理的作业移入存档。
Queuety::cancel_workflow( $workflow_id );
如果工作流已处于 completed 或 cancelled 状态,则抛出 RuntimeException。详情请参阅 取消。
Queuety::rewind_workflow( $workflow_id, $to_step )
将工作流回退到之前的步骤,并从该处重新运行。给定步骤的状态会从事件日志 state_after 中恢复,然后将下一步加入队列。
Queuety::rewind_workflow( $workflow_id, to_step: 1 );
如果目标步骤没有记录的状态,则抛出 RuntimeException。需要使用 工作流事件日志。详情请参阅 时间回溯。
Queuety::fork_workflow( $workflow_id )
将正在运行的工作流按当前状态分叉为一个独立副本。返回新工作流 ID。
$forked_id = Queuety::fork_workflow( $workflow_id );
分叉后的工作流拥有自己的 ID,且独立于原工作流运行。详情请参阅 分叉。
Queuety::export_workflow( $workflow_id )
将工作流的完整执行历史导出为可由 JSON 序列化的数组。其中包含工作流行、所有作业、工作流事件和日志条目。
$data = Queuety::export_workflow( $workflow_id );
有关 JSON 结构和使用场景,请参阅 导出与重放。
Queuety::replay_workflow( $data )
在当前环境中重放已导出的工作流。根据导出数据创建一个新工作流,并返回新工作流 ID。
$new_id = Queuety::replay_workflow( $data );
详情请参阅 导出与重放。
Queuety::replace_wp_cron()
将内置 WordPress cron 系统替换为 Queuety 的调度器。拦截 wp_schedule_event()、wp_unschedule_event() 和 wp_get_scheduled_event(),并通过 Queuety 工作进程路由定期事件。
Queuety::replace_wp_cron();
仅在加载了 WordPress 时有效。详情请参阅 WP-Cron替换。
Queuety::restore_wp_cron()
移除 Queuety cron 桥接钩子,以恢复 WordPress 默认的 cron 行为。
Queuety::restore_wp_cron();
有关限制,请参阅 WP-Cron替换。
Queuety::signal( $workflow_id, $name, $data )
向工作流发送信号。如果工作流当前正在等待此信号,它会立即恢复运行。否则,信号会被存储起来,并在工作流到达对应的 wait_for_signal 步骤时获取。
Queuety::signal( $workflow_id, 'approved' );
// With data merged into workflow state
Queuety::signal( $workflow_id, 'approved', [
'approved_by' => 'admin@example.com',
] );
详情请参阅 工作流信号。
Queuety::approve_workflow( $workflow_id, $data = [], $signal_name = 'approval' )
用于审批流程的语义包装器,包装 signal()。
Queuety::approve_workflow( $workflow_id, [
'reviewer' => 'editor@example.com',
] );
Queuety::reject_workflow( $workflow_id, $data = [], $signal_name = 'rejected' )
用于拒绝流程的语义包装器,包装 signal()。
Queuety::reject_workflow( $workflow_id, [
'reason' => 'needs citations',
] );
Queuety::submit_workflow_input( $workflow_id, $data = [], $signal_name = 'input' )
用于结构化人工输入的语义包装器,包装 signal()。
Queuety::submit_workflow_input( $workflow_id, [
'notes' => 'Ship after legal review',
] );
Queuety::put_artifact( $workflow_id, $artifact_key, $content, $kind = 'json', $step_index = null, $metadata = [] )
为工作流存储一个持久化工件。
Queuety::put_artifact(
$workflow_id,
'research_brief',
[ 'summary' => 'done' ],
'json',
metadata: [ 'source' => 'agent' ],
);
Queuety::put_current_artifact( $artifact_key, $content, $kind = 'json', $metadata = [] )
为当前正在执行的工作流步骤存储一个工件。
Queuety::put_current_artifact(
'draft',
[ 'status' => 'ready' ],
'json',
);
Queuety::workflow_artifact( $workflow_id, $artifact_key )
获取工作流中存储的一个工件。
$artifact = Queuety::workflow_artifact( $workflow_id, 'draft' );
Queuety::workflow_artifacts( $workflow_id, $include_content = false )
列出工作流的工件。
$artifacts = Queuety::workflow_artifacts( $workflow_id );
Queuety::delete_workflow_artifact( $workflow_id, $artifact_key )
删除工作流中的一个工件。
Queuety::delete_workflow_artifact( $workflow_id, 'draft' );
状态机
Queuety::machine( $name )
开始构建状态机。返回一个 StateMachineBuilder。
use Queuety\Enums\StateMachineStatus;
$machine_id = Queuety::machine( 'agent_session' )
->state( 'awaiting_user' )
->on( 'user_message', 'planning' )
->state( 'planning' )
->action( PlanSessionAction::class )
->on( 'planned', 'completed' )
->state( 'completed', StateMachineStatus::Completed )
->dispatch( [ 'thread_id' => 42 ] );
StateMachineBuilder 方法
| 方法 | 说明 |
|---|---|
initial( string $state_name ) |
显式设置初始状态。 |
state( string $state_name, ?StateMachineStatus $terminal_status = null ) |
开始配置一个状态。 |
action( string|array $action_class ) |
为当前状态注册一个排队的进入动作。传入类名,或包含 class、payload 和 config 的结构化定义;payload 会以 $payload 的形式传递给 StateAction::handle()。 |
on( string $event, string $target, string|array|null $guard_class = null, ?string $name = null ) |
为当前状态注册一个事件转换。守卫接受与 action() 相同的结构化形式。 |
on_queue( string $queue ) |
设置用于排队状态动作的队列。 |
with_priority( Priority $priority ) |
设置排队状态动作的优先级。 |
max_attempts( int $max_attempts ) |
设置排队状态动作的重试限制。 |
version( string $version ) |
为状态机定义添加应用级版本标签。 |
idempotency_key( string $key ) |
使用调用方提供的键,使调度具有持久性。使用相同的键再次调度时,会返回原状态机 ID。 |
dispatch( array $initial_state = [] ) |
调度状态机并返回状态机 ID。 |
状态进入动作类还可以提供可选的 config() 方法,其资源策略键与工作流步骤支持的相同:concurrency_group、concurrency_limit 和 cost_units。
Queuety::dispatch_state_machine_definition( $definition, $initial_state = [], $options = [] )
调度序列化的状态机定义包。大多数应用代码应优先使用 machine()->dispatch()。此低级方法供适配器使用,使其无需直接依赖构建器即可启动状态机。
$machine_id = Queuety::dispatch_state_machine_definition(
$definition,
[ 'thread_id' => 42 ],
[ 'idempotency_key' => 'thread:42' ],
);
Queuety::machine_status( $machine_id )
获取当前状态机状态。返回一个 StateMachineState 对象或 null。
$status = Queuety::machine_status( $machine_id );
echo $status->name; // 'agent_session'
echo $status->status->value; // 'waiting_event'
echo $status->current_state; // 'awaiting_review'
print_r( $status->state ); // public machine state
print_r( $status->available_events ); // valid incoming events in the current state
StateMachineState 还提供:
definition_versiondefinition_hashidempotency_keyerror_messagecurrent_actionterminal_status
Queuety::machine_event( $machine_id, $event_name, $payload = [] )
向等待中的状态机发送一个外部事件。
Queuety::machine_event(
$machine_id,
'approve',
[
'approved' => true,
'reviewer' => 'editor@example.com',
]
);
载荷可供转换守卫使用;事件被接受后,载荷会合并到公开的状态机状态中。
Queuety::list_machines( $limit = 50, $status = null )
列出已持久化的状态机行以供检查。
$machines = Queuety::list_machines();
$waiting = Queuety::list_machines( status: 'waiting_event' );
每行包含状态机 id、名称、状态、当前状态、定义版本、定义哈希值、幂等键和生命周期时间戳。
Queuety::machine_timeline( $machine_id, $limit = 100, $offset = 0 )
获取一个状态机的持久化事件时间线。
$timeline = Queuety::machine_timeline( $machine_id );
$page_two = Queuety::machine_timeline( $machine_id, 100, 100 );
每个事件行都包含:id、machine_id、job_id、state_name、handler、event、event_name、transition_name、queue、attempt、input、output、state_before、state_after、context、artifacts、chunks、error、duration_ms、created_at。
Queuety::machine_trace( $machine_id )
获取供状态机调试器使用的标准化跟踪包 UI。
$trace = Queuety::machine_trace( $machine_id );
跟踪包含 machine、分组后的 states、原始 events、关联的动作 jobs、logs、artifacts 和 chunks。
Queuety::machine_state_at( $machine_id, $event_id )
获取特定状态机跟踪事件后的公开状态;如果未找到,则返回 null。
$state = Queuety::machine_state_at( $machine_id, $event_id );
有关生命周期模型和使用模式,请参阅 状态机。
工作流模板
Queuety::define_workflow( $name )
创建一个工作流构建器,用作模板。
$builder = Queuety::define_workflow( 'onboarding' )
->then( CreateAccountHandler::class )
->then( SendWelcomeEmailHandler::class );
Queuety::register_workflow_template( $builder )
注册工作流模板。
Queuety::register_workflow_template( $builder );
Queuety::run_workflow( $name, $payload, $options = [] )
按名称调度已注册的工作流模板。返回工作流 ID。
$workflow_id = Queuety::run_workflow( 'onboarding', [ 'email' => 'user@example.com' ] );
$workflow_id = Queuety::run_workflow(
'onboarding',
[ 'email' => 'user@example.com' ],
[ 'idempotency_key' => 'onboarding:user@example.com' ],
);
如果模板尚未注册,则抛出 RuntimeException。
Queuety::dispatch_workflow_definition( $definition, $payload, $options = [] )
根据运行时定义包调度工作流。
大多数应用代码应优先使用 run_workflow() 或 workflow()->dispatch()。此低级方法供可复用适配器使用,使其无需依赖内部工作流管理器方法即可调度序列化的工作流定义。
$workflow_id = Queuety::dispatch_workflow_definition(
$definition,
[ 'email' => 'user@example.com' ],
[ 'idempotency_key' => 'onboarding:user@example.com' ],
);
Queuety::on_action( $hook, $workflow, $map = null, $when = null, $idempotency_key = null, $priority = 10, $accepted_args = null )
注册一个用于调度工作流的 WordPress 动作。
Queuety::on_action(
'save_post',
workflow: 'content_review',
map: static fn ( int $post_id, object $post, bool $update ): array => [
'post_id' => $post_id,
'post_type' => $post->post_type,
'update' => $update,
],
when: static fn ( int $post_id, object $post ): bool => 'post' === $post->post_type,
idempotency_key: static fn ( int $post_id ): string => "save_post:{$post_id}",
);
$workflow 可以是以下任一项:
- 已注册的工作流模板名称
- 内联的
WorkflowBuilder
map、when 和 idempotency_key 会在当前 WordPress 请求中同步运行。只有工作流步骤本身会在调度后异步运行。
完整指南请参阅 动作触发器。
Queuety::workflow_templates()
获取工作流模板注册表。
$registry = Queuety::workflow_templates();
$template = $registry->get( 'onboarding' ); // WorkflowTemplate or null
Queuety::load_workflows( $directory, $recursive )
从目录中加载并注册所有工作流文件。每个 .php 文件都应返回一个 WorkflowBuilder。返回已注册的工作流数量。
$count = Queuety::load_workflows( __DIR__ . '/workflows/' );
$count = Queuety::load_workflows( __DIR__ . '/workflows/', recursive: true );
Queuety::load_workflow_file( $file_path )
加载并注册单个工作流文件。如果文件未返回构建器,则返回 WorkflowTemplate 或 null。
$template = Queuety::load_workflow_file( __DIR__ . '/workflows/onboard-user.php' );
调度
Queuety::schedule( $handler, $payload )
创建定期调度。返回一个 PendingSchedule 构建器。
Queuety::schedule( 'cleanup_handler' )
->every( '1 hour' )
->on_queue( 'maintenance' );
Queuety::schedule( 'nightly_report' )
->cron( '0 3 * * *' )
->on_queue( 'reports' );
PendingSchedule 方法
| 方法 | 说明 |
|---|---|
every( string $interval ) |
设置间隔表达式(e.g、1 hour、30 minutes) |
cron( string $expression ) |
设置 5 字段的 cron 表达式 |
overlap( OverlapPolicy $policy ) |
设置重叠策略(默认值:Allow)。请参阅 调度。 |
on_queue( string $queue ) |
设置目标队列(默认值:default) |
id() |
强制调度并返回调度 ID |
Queuety::scheduler()
获取内部的 Scheduler 实例。
$scheduler = Queuety::scheduler();
$schedules = $scheduler->list();
$scheduler->remove( 'handler_name' );
$count = $scheduler->tick(); // manually trigger
处理程序注册
Queuety::register( $name, $class )
按名称注册处理程序类。
Queuety::register( 'send_email', SendEmailHandler::class );
Queuety::discover_handlers( $directory, $namespace )
从目录中自动发现并注册处理程序类。返回已注册的处理程序数量。
$count = Queuety::discover_handlers( __DIR__ . '/handlers', 'MyPlugin\\Handlers' );
Queuety::registry()
获取处理程序注册表。
$registry = Queuety::registry();
可观测性
Queuety::logger()
获取用于查询日志条目的 Logger 实例。
$logger = Queuety::logger();
$logs = $logger->for_job( 42 );
$logs = $logger->for_workflow( 7 );
$logs = $logger->for_handler( 'send_email', 50 );
$logs = $logger->for_event( LogEvent::Failed, 50 );
$logs = $logger->since( new \DateTimeImmutable( '-1 hour' ), 100 );
$count = $logger->purge( 30 );
Queuety::metrics()
获取 Metrics 实例。
$stats = Queuety::metrics()->handler_stats( 60 ); // last 60 minutes
Queuety::webhook_notifier()
获取 WebhookNotifier 实例。
$notifier = Queuety::webhook_notifier();
$id = $notifier->register( 'job.buried', 'https://hooks.slack.com/...' );
$webhooks = $notifier->list();
$notifier->remove( $id );
Queuety::rate_limiter()
获取 RateLimiter 实例。
$limiter = Queuety::rate_limiter();
$limiter->register( 'call_openai', 60, 60 );
缓存
Queuety::cache()
获取当前活动的缓存后端实例。
$cache = Queuety::cache();
$cache->set( 'my_key', 'my_value', 60 );
$value = $cache->get( 'my_key' );
Queuety::set_cache( $cache )
覆盖缓存后端。若要使用自定义实现,请在调用 Queuety::init() 之前执行此操作。
Queuety::set_cache( new RedisCache() );
Queuety::init( $connection );
QUEUETY_CACHE_TTL
默认缓存 TTL(秒)(默认值:5)。在 wp-config.php 中设置此常量,可更改内部缓存操作使用的默认 TTL。
define( 'QUEUETY_CACHE_TTL', 10 );
有关后端和自动检测的详情,请参阅 缓存。
状态机事件日志
Queuety::machine_events()
获取 StateMachineEventLog 实例。
$log = Queuety::machine_events();
工作流事件日志
Queuety::workflow_events()
获取 WorkflowEventLog 实例。
$log = Queuety::workflow_events();
Queuety::workflow_timeline( $workflow_id, $limit = 100, $offset = 0 )
获取工作流的完整事件时间线。返回按 ID 排序的事件行数组。
$events = Queuety::workflow_timeline( $workflow_id );
$next = Queuety::workflow_timeline( $workflow_id, 100, 100 );
每个事件行都包含:id、workflow_id、job_id、parent_event_id、step_index、step_name、step_type、handler、event、queue、attempt、input、output、state_before、state_after、context、artifacts、chunks、error、error_message(从 error.message 复制而来)、duration_ms 和 created_at。
Queuety::workflow_trace( $workflow_id )
获取供工作流调试器使用的标准化跟踪包 UI。
$trace = Queuety::workflow_trace( $workflow_id );
跟踪包含 workflow、分组后的 steps、原始 events、jobs、logs、artifacts、chunks、signals 和 wait_dependencies。
Queuety::trace_input( $input )
为当前正在执行的工作流步骤设置应用级输入。
Queuety::trace_output( $output )
为当前正在执行的工作流步骤设置应用级输出。
Queuety::trace_context( array $context )
将应用级上下文合并到当前正在执行的工作流步骤中。
Queuety::workflow_state_at( $workflow_id, $step_index )
获取特定工作流步骤完成或恢复运行后的公开状态;如果未找到,则返回 null。
$state = Queuety::workflow_state_at( $workflow_id, 2 );
有关使用场景和 CLI 命令,请参阅 工作流事件日志。
内部实例
这些方法会返回供高级使用场景使用的内部实例。
| 方法 | 返回值 | 说明 |
|---|---|---|
Queuety::queue() |
Queue |
队列操作(认领、释放、归档) |
Queuety::worker() |
Worker |
工作进程控制 |
Queuety::workflow_manager() |
Workflow |
工作流编排 |
Queuety::machines() |
StateMachine |
状态机生命周期管理 |
Queuety::connection() |
Connection |
数据库连接 |
Queuety::batch_manager() |
BatchManager |
批处理生命周期管理(取消、清理) |
Queuety::chunk_store() |
ChunkStore |
流式处理步骤的分块持久化 |
Queuety::machine_events() |
StateMachineEventLog |
状态机跟踪事件和标准化跟踪包 |
Queuety::workflow_events() |
WorkflowEventLog |
工作流跟踪事件和标准化跟踪包 |
Queuety::resource_manager() |
ResourceManager |
工作进程准入配置、加权预算和系统内存检查 |
Queuety::cache() |
Cache |
缓存后端实例 |
测试
Queuety::fake()
用内存中的伪对象替换队列以进行测试。返回一个 QueueFake 实例,该实例会记录已调度的作业,而不访问数据库。create_batch() 还会记录伪批处理元数据;链式调用通过其调度的各个已推送作业进行断言。
$fake = Queuety::fake();
SendEmailJob::dispatch( 'user@example.com', 'Hello', 'Hi!' );
$fake->assert_pushed( SendEmailJob::class );
Queuety::reset()
重置所有内部状态,包括队列伪对象。在 tearDown() 中调用。
Queuety::reset();
QueueFake 方法
| 方法 | 说明 |
|---|---|
assert_pushed( string $class, ?Closure $callback ) |
断言已推送某个作业类。可选回调会根据作业数据进行筛选。 |
assert_pushed_times( string $class, int $count ) |
断言某个作业恰好推送了 N 次。 |
assert_not_pushed( string $class ) |
断言某个作业从未被推送。 |
assert_nothing_pushed() |
断言没有推送任何作业。 |
assert_batched( ?Closure $callback ) |
断言已调度一个批处理。可选回调会根据批处理数据进行筛选。 |
pushed( string $class ) |
获取某个类的所有已记录调度。返回一个数组。 |
batches() |
获取所有已记录的批处理。返回一个数组。 |
reset() |
清除所有已记录的作业和批处理。 |
完整示例请参阅 测试。
接口
Handler
简单作业处理程序的接口。
interface Handler {
public function handle( array $payload ): void;
public function config(): array;
}
config() 可以返回 queue、max_attempts、backoff、rate_limit、concurrency_group、concurrency_limit 和 cost_units。
Step
工作流步骤处理程序的接口。
interface Step {
public function handle( array $state ): array;
public function config(): array;
}
config() 可以返回 max_attempts、backoff、concurrency_group、concurrency_limit 和 cost_units。
Contracts\ForEachHandler
动态 for-each 分支处理程序的接口。
namespace Queuety\Contracts;
interface ForEachHandler {
public function handle_item( array $state, mixed $item, int $index ): array;
public function config(): array;
}
config() 可以返回 max_attempts、backoff、rate_limit、concurrency_group、concurrency_limit 和 cost_units。
Contracts\ForEachReducer
for-each 结果的可选归约器。
namespace Queuety\Contracts;
interface ForEachReducer {
public function reduce( array $state, array $for_each ): array;
}
Contracts\Compensation
步骤补偿处理程序的接口。
namespace Queuety\Contracts;
interface Compensation {
public function handle( array $state ): void;
}
Contracts\RepeatCondition
当状态键比较过于有限时,供 repeat_until() 和 repeat_while() 使用的循环谓词接口。
namespace Queuety\Contracts;
interface RepeatCondition {
public function matches( array $state ): bool;
}
Contracts\StateAction
排队状态进入动作的接口。
namespace Queuety\Contracts;
interface StateAction {
public function handle( array $state, ?string $event = null, array $event_payload = [], array $payload = [] ): array|string;
}
如果状态机定义中包含结构化的 payload,$payload 会携带该定义。返回公开状态更新。如果动作应立即转换状态,请包含 _event,并可选地包含 _event_payload。
状态动作还可以定义一个可选的 config() 方法。进入动作排队时,Queuety 会从该方法读取 concurrency_group、concurrency_limit 和 cost_units。
Contracts\StateGuard
状态机转换守卫的接口。
namespace Queuety\Contracts;
interface StateGuard {
public function allows( array $state, array $event_payload, string $event, array $payload = [] ): bool;
}
Contracts\Job
自包含、可调度作业类的接口。作业类将载荷封装为公共属性,并将执行逻辑放在 handle() 中。
namespace Queuety\Contracts;
interface Job {
public function handle(): void;
}
作业类可以选择定义一个 middleware() 方法,该方法返回一个包含多个 Contracts\Middleware 实例的数组。
Contracts\Cache
缓存后端的接口。有关内置实现和自定义后端,请参阅 缓存。
namespace Queuety\Contracts;
interface Cache {
public function get( string $key ): mixed;
public function set( string $key, mixed $value, int $ttl = 0 ): void;
public function delete( string $key ): void;
public function has( string $key ): bool;
public function add( string $key, mixed $value, int $ttl = 0 ): bool;
public function flush(): void;
}
| 方法 | 返回值 | 说明 |
|---|---|---|
get( $key ) |
mixed |
获取一个值。如果未找到或已过期,则返回 null。 |
set( $key, $value, $ttl ) |
void |
存储一个值。TTL 为 0 表示永不过期。 |
delete( $key ) |
void |
移除一个值。 |
has( $key ) |
bool |
检查键是否存在且未过期。 |
add( $key, $value, $ttl ) |
bool |
原子性的“仅当键不存在时设置”。如果设置了该值,则返回 true。 |
flush() |
void |
从缓存中移除所有项目。 |
WorkflowEventLog
记录工作流步骤转换及完整的跟踪上下文。通过 Queuety::workflow_events() 访问。
| 方法 | 返回值 | 说明 |
|---|---|---|
record_event( array $event ) |
void |
记录原始跟踪事件 |
record_step_started( ... ) |
void |
记录 step_started 事件,以及执行前的输入和状态 |
record_step_completed( ... ) |
void |
记录 step_completed 事件,以及输入、输出、执行前状态和执行后状态 |
record_step_failed( ... ) |
void |
记录 step_failed 事件,以及跟踪上下文和结构化错误详情 |
get_timeline( int $workflow_id, ?int $limit = 100, int $offset = 0 ) |
array |
按顺序获取工作流跟踪事件,可选分页 |
get_trace( int $workflow_id ) |
array |
获取标准化跟踪包 |
get_state_at_step( int $workflow_id, int $step_index ) |
array|null |
获取特定步骤完成或恢复运行后的公开状态 |
prune( int $older_than_days ) |
int |
删除早于指定天数的事件。返回删除的行数。 |
StateMachineEventLog
记录状态机生命周期、动作、转换和守卫事件,所用的跟踪字段与工作流事件相同。
| 方法 | 返回值 | 说明 |
|---|---|---|
record_event( array $event ) |
void |
记录一条原始机器跟踪事件 |
get_timeline( int $machine_id, ?int $limit = 100, int $offset = 0 ) |
array |
按顺序获取机器跟踪事件,可选择分页 |
get_trace( int $machine_id ) |
array |
获取规范化的机器跟踪数据包 |
get_state_at_event( int $machine_id, int $event_id ) |
array|null |
获取特定机器跟踪事件之后的公开状态 |
prune( int $older_than_days ) |
int |
删除早于指定天数的事件。返回已删除的行数。 |
Contracts\StreamingStep
用于生成数据块流的工作流步骤处理器接口。每个生成的值都会立即持久化到数据库。请参阅 流式步骤。
namespace Queuety\Contracts;
interface StreamingStep {
public function stream( array $state, array $existing_chunks = [] ): \Generator;
public function on_complete( array $chunks, array $state ): array;
public function config(): array;
}
| 方法 | 说明 |
|---|---|
stream( $state, $existing_chunks ) |
生成字符串数据块。每次生成都会立即写入数据库。重试时,$existing_chunks 包含之前已持久化的数据块。 |
on_complete( $chunks, $state ) |
流结束后调用。返回要合并到工作流状态中的数据。 |
config() |
可选配置。支持 max_attempts、backoff、concurrency_group、concurrency_limit 和 cost_units。 |
ChunkStore
管理流式步骤的数据块持久化。通过 Queuety::chunk_store() 访问。
| 方法 | 返回值 | 说明 |
|---|---|---|
get_chunks( int $job_id ) |
string[] |
获取某个作业的所有数据块,并按数据块索引排序 |
append_chunk( int $job_id, int $chunk_index, string $content, ?int $workflow_id, ?int $step_index ) |
void |
追加单个数据块 |
clear_chunks( int $job_id ) |
void |
删除某个作业的所有数据块 |
chunk_count( int $job_id ) |
int |
统计某个作业的数据块数量 |
get_accumulated( int $job_id ) |
string |
将所有数据块拼接成一个字符串 |
Heartbeat
用于在步骤处理器和流式步骤中发送活动心跳的静态辅助类。请参阅 心跳。
| 方法 | 说明 |
|---|---|
Heartbeat::init( int $job_id, Connection $conn ) |
设置作业上下文。由工作进程自动调用。 |
Heartbeat::beat( array $progress = [] ) |
发送心跳。更新 reserved_at,并可选择将进度数据存储在 heartbeat_data 中。 |
Heartbeat::clear() |
清除作业上下文。由工作进程自动调用。 |
Heartbeat::current_job_id() |
获取当前作业 ID(用于测试)。 |
Contracts\Middleware
作业中间件接口。中间件以洋葱式管道包装作业执行过程。
namespace Queuety\Contracts;
interface Middleware {
public function handle( object $job, \Closure $next ): void;
}
特征
Dispatchable
在实现 Contracts\Job 的作业类上提供静态分发方法。构造函数参数会传入以创建作业实例。
use Queuety\Contracts\Job;
use Queuety\Dispatchable;
class SendEmailJob implements Job {
use Dispatchable;
// ...
}
// Dispatches a new SendEmailJob instance
SendEmailJob::dispatch( 'user@example.com', 'Subject', 'Body' );
| 方法 | 返回值 | 说明 |
|---|---|---|
dispatch( ...$args ) |
PendingJob |
创建实例并分发作业 |
dispatch_if( bool $condition, ...$args ) |
PendingJob|null |
仅当 $condition 为 true 时分发作业 |
dispatch_unless( bool $condition, ...$args ) |
PendingJob|null |
仅当 $condition 为 false 时分发作业 |
with_chain( array $jobs ) |
ChainBuilder |
从此作业类启动一个链 |
// Conditional dispatch
SendEmailJob::dispatch_if( $user->wants_email, $user->email, 'Hello', 'Hi!' );
SendEmailJob::dispatch_unless( $maintenance_mode, $user->email, 'Hello', 'Hi!' );
// Chain from a job class
FetchDataJob::with_chain( [
new ProcessDataJob(),
new NotifyCompleteJob(),
] )->dispatch();
作业属性
作业类可以声明公共属性,工作进程会通过反射读取这些属性,以覆盖重试和超时行为。
| 属性 | 类型 | 说明 |
|---|---|---|
$tries |
int |
作业被搁置前允许尝试的最大次数 |
$timeout |
int |
最大执行时间,单位为秒(需要 pcntl) |
$backoff |
array |
每次重试的递增延迟值,单位为秒 |
class ImportProductsJob implements Job {
use Dispatchable;
public int $tries = 5;
public int $timeout = 120;
public array $backoff = [ 10, 30, 60, 120 ];
// ...
}
failed() 钩子
作业耗尽所有重试次数而被搁置后,如果作业实例定义了 failed() 方法,工作进程就会调用该方法。
public function failed( \Throwable $exception ): void {
error_log( "Job failed: {$exception->getMessage()}" );
}
内置中间件
所有中间件类都实现 Contracts\Middleware,并位于 Queuety\Middleware 命名空间中。
| 类 | 说明 |
|---|---|
RateLimited( int $max, int $window ) |
限制速率:每 $window 秒最多执行 $max 次 |
Timeout( int $seconds ) |
$seconds 秒后终止作业(需要 pcntl) |
UniqueJob( ?string $key ) |
通过数据库锁防止并发执行 |
WithoutOverlapping( string $key, int $release_after ) |
通过自动过期的锁防止执行重叠 |
ThrottlesExceptions( int $max_attempts, int $decay_minutes ) |
外部服务宕机时限制异常频率,防止作业激增 |
有关用法和示例,请参阅 中间件。
枚举
Priority
enum Priority: int {
case Low = 0;
case Normal = 1;
case High = 2;
case Urgent = 3;
}
JobStatus
enum JobStatus: string {
case Pending = 'pending';
case Processing = 'processing';
case Completed = 'completed';
case Failed = 'failed';
case Buried = 'buried';
}
WorkflowStatus
enum WorkflowStatus: string {
case Running = 'running';
case Completed = 'completed';
case Failed = 'failed';
case Paused = 'paused';
case WaitingForSignal = 'waiting_for_signal';
case WaitingForWorkflows = 'waiting_for_workflows';
case Cancelled = 'cancelled';
}
StateMachineStatus
enum StateMachineStatus: string {
case Running = 'running';
case WaitingEvent = 'waiting_event';
case Completed = 'completed';
case Failed = 'failed';
case Paused = 'paused';
case Cancelled = 'cancelled';
}
BackoffStrategy
enum BackoffStrategy: string {
case Fixed = 'fixed';
case Linear = 'linear';
case Exponential = 'exponential';
}
ForEachMode
enum ForEachMode: string {
case All = 'all';
case FirstSuccess = 'first_success';
case Quorum = 'quorum';
}
WaitMode
enum WaitMode: string {
case All = 'all';
case Any = 'any';
case Quorum = 'quorum';
}
LogEvent
enum LogEvent: string {
case Started = 'started';
case Completed = 'completed';
case Failed = 'failed';
case Buried = 'buried';
case Retried = 'retried';
case WorkflowStarted = 'workflow_started';
case WorkflowCompleted = 'workflow_completed';
case WorkflowFailed = 'workflow_failed';
case WorkflowPaused = 'workflow_paused';
case WorkflowResumed = 'workflow_resumed';
case WorkflowCancelled = 'workflow_cancelled';
case WorkflowRewound = 'workflow_rewound';
case WorkflowForked = 'workflow_forked';
case WorkflowDeadlineExceeded = 'workflow_deadline_exceeded';
case Debug = 'debug';
}
OverlapPolicy
enum OverlapPolicy: string {
case Allow = 'allow';
case Skip = 'skip';
case Buffer = 'buffer';
}
有关各项策略的工作方式,请参阅 调度。
属性
#[QueuetyHandler]
用于自动注册的 PHP 8 属性。请参阅 PHP 属性。
use Queuety\Attributes\QueuetyHandler;
#[QueuetyHandler( name: 'send_email', queue: 'emails', max_attempts: 5 )]
class SendEmailHandler implements Handler {
// ...
}
CLI 桥接
Queuety::cli_command()
返回已发布的 WP-CLI 根命令名称。
默认根命令为 queuety。如果要以不同名称发布命令,请在 Queuety 启动之前定义 QUEUETY_CLI_COMMAND。
Queuety::cli_command_map()
返回可序列化的 Queuety CLI 目录,供测试框架了解已发布的命令范围,而无需扫描 WP-CLI 类。
每个条目包括:
- 稳定的操作 ID
- 相对 CLI 路径
- WP-CLI 处理器类和方法
- 可能的执行目标
- 用于将原始 CLI 参数规范化为执行计划的适配器
Queuety::resolve_cli_command( $path, $args, $assoc_args )
将解析后的 CLI 调用转换为测试框架应运行的执行计划。
$plan = Queuety::resolve_cli_command(
[ 'workflow', 'export' ],
[ '42' ],
[ 'output' => '/tmp/workflow.json' ]
);
echo $plan['callable']; // Queuety\Queuety::export_workflow_to_file
print_r( $plan['arguments'] );
执行计划会有意考虑传输方式:
- 命令会解析为带有规范化参数的公共 PHP 可调用对象
- 目录会预先列出所有可能的执行目标,而
callable和transport会标识解析输入所选择的分支
这是代理测试框架使用 Queuety 的标准方式:使用稳定的操作 ID、公共 API 目标,并由适配器负责规范化仅与 CLI 有关的事项,例如队列默认值、JSON 负载解码、工作进程池分支和工作流导出文件处理。