4: 运行时助手和调度
两个消费者在没有你自己调用 /dispatch 的情况下运行守护进程:异步运行时助手和调度器。
4.1: 运行时助手
Phlo 的助手在应用选择加入时,都会使用池来运行目标,否则会回退到一次性子进程:
| 助手 | 功能 |
|---|---|
phlo_sync('Class::method', ...$args) |
运行一个目标并等待其返回值 |
phlo_async('Class::method', ...$args) |
排队一个目标,火并忘;一旦被接受就返回 |
await($job, $job, ...) |
并发运行多个目标并收集它们的结果 |
phlo_stream('Class::method', ...$args) |
逐行输出目标的结果 |
选择加入是在应用入口点中的一个常量:
phlo_app(
id: 'Api',
host: 'api.example.com',
daemon: 3001,
);
设置了 daemon 时,助手通过 app 路径调度到池中;没有它时,它们会像之前一样生成一个一次性进程。无论哪种方式,应用代码都是相同的,因此采用守护进程只会改变吞吐量。
当一个请求分发时,增益最大。await() 超过一百个作业时,在一次性路径上会有一百个应用启动,但在使用守护进程时,会有一百个调度到常驻池中,受工作者数量的限制,而不是无限制的子进程爆发:
$results = await(
['translate::run', 'nl', $text],
['translate::run', 'de', $text],
['translate::run', 'fr', $text],
)4.2: 不使用 cron 的调度
守护进程可以在一个时间间隔内运行目标,这取代了 tasks 资源后面的每个应用的 cron 条目。每个调度条目是 {app, target, every, build}:绝对的 app.php 路径、目标、以秒为单位的时间间隔,以及是否一次性运行。每个条目都会在其时间间隔内触发,第一次运行是在启动后一个时间间隔,就像 cron tick 一样:
[
{ app: '/srv/api/www/app.php', target: 'tasks::run', every: 60, build: false },
{ app: '/srv/dashboard/www/app.php', target: 'fleet::poll', every: 120, build: true },
]
下游的一切保持不变:相同的 %app->tasks 匹配,相同的到期检查,相同的磁盘状态。对于没有守护进程的主机,Cron 仍然是后备选项;你只能选择一个触发器,而不是两个。