Command Signals
friendsofhyperf/command-signals 為 Hyperf 命令提供基於協程的 POSIX 信號處理能力。
安裝
composer require friendsofhyperf/command-signals該組件支持 Hyperf 3.2,並會被自動發現。它的 ConfigProvider 不會發布任何配置。下方 命令示例假設應用已經安裝 hyperf/command;該組件沒有將其聲明為依賴。
實現通過 Hyperf Engine 處理信號,並調用 posix_getpid() 和 posix_kill()。請在支持 POSIX 信號且可運行協程的 Swoole 或 Swow 環境中使用。PHP POSIX 擴展必須提供上述兩個 函數。Composer 建議安裝 ext-swoole >= 4.6.0 或 ext-swow >= 0.1.0,但沒有將 POSIX 擴展聲明為依賴。
使用
在命令中引入 InteractsWithSignals,然後調用 trap() 並傳入一個信號編號或信號編號數組。 回調會接收到信號編號。
namespace App\Command;
use FriendsOfHyperf\CommandSignals\Traits\InteractsWithSignals;
use Hyperf\Command\Annotation\Command;
use Hyperf\Command\Command as HyperfCommand;
use Psr\Container\ContainerInterface;
#[Command]
class FooCommand extends HyperfCommand
{
use InteractsWithSignals;
public function __construct(protected ContainerInterface $container)
{
parent::__construct('foo');
}
public function configure()
{
parent::configure();
$this->setDescription('Hyperf Demo Command');
}
public function handle()
{
$this->trap([SIGINT, SIGTERM], function (int $signo): void {
$this->warn(sprintf('Received signal %d, exiting...', $signo));
});
sleep(10);
$this->info('Bye!');
}
}首次調用 trap() 時,它會通過容器創建 SignalRegistry,並在當前協程結束時自動清空回調。 同一個信號可以註冊多個回調;收到該信號時,這些回調會併發執行。
每個已註冊信號只會被處理一次。回調執行完成後,註冊器會停止等待,並再次向當前進程發送同一 信號,因此操作系統通常會執行該信號的默認動作。
使用 untrap() 清空一個信號、多個信號或全部信號的回調。它不會取消已經啓動的等待協程; 如果之後收到該信號,註冊器仍會在不執行回調後再次向進程發送該信號。
$this->untrap(SIGINT);
$this->untrap([SIGINT, SIGTERM]);
$this->untrap();API
Trait 向命令提供以下受保護方法:
trap(array|int $signo, callable $callback): voiduntrap(null|array|int $signo = null): void
SignalRegistry 也是公開類。其構造函數為 __construct(int $timeout = 1, int $concurrentLimit = 0);timeout 是每次等待嘗試的 超時秒數,concurrentLimit 用於限制併發執行的回調數量,值為 0 表示不限制併發數。它 提供以下方法:
register(int|array $signo, callable $signalHandler): voidunregister(null|int|array $signo = null): void
unregister() 會清空所選信號的回調;傳入 null 會清空全部回調。
運行
- 按下
Ctrl + C發送SIGINT。
$ hyperf foo
^CReceived signal 2, exiting...- 發送
SIGTERM,例如使用killall php。
$ hyperf foo
Received signal 15, exiting...
[1] 51936 terminated php bin/hyperf.php foo