ReactPHP 1.2のLoopと開始時のエラー
ReactPHP のバージョン1.2からイベントループをわざわざ作成しなくても良くなったようだ。
代わりにLoopクラスのstatic関数を使う。
<?php use React\EventLoop\Loop; Loop::addPeriodicTimer(1, function () { static $count = 0; echo ++$count . "\n"; });
$loop->run()
さえもないが、Loopクラスがshutdown関数を登録して、プログラムの最後にrun()
が実行される。
作ったイベントループインスタンスを引き回さなくてよくて便利になった。ただ、プログラム本体がshutdown関数の中で実行されることになるので他のshutdown関数との実行順序が問題になるかもしれない。(これは実装時のレビューでも指摘されたようだ。)
明示的にループを実行することで回避できる。
<?php use React\EventLoop\Loop; Loop::addPeriodicTimer(1, function () { static $count = 0; echo ++$count . "\n"; }); Loop::run(); // Loopクラスが登録するshutdown関数はループを実行済みとしてなにもしない
本題だが、イベントループの準備後に問題が起きてプログラムを開始できないケースというのもある。
<?php use React\EventLoop\Loop; Loop::addPeriodicTimer(1, function () { static $count = 0; echo ++$count . "\n"; }); if ('failed') { // 問題発生 echo "セットアップ中のエラー\n"; exit(1); } Loop::run();
この場合、単にexitしたいにも関わらず、やはりループが実行されてしまう。
準備が中途半端な状態で実行されてしまうのは困る。
対策としては2つある。一つはtrigger_errorを呼ぶか、catchされない例外を投げる。
<?php use React\EventLoop\Loop; Loop::addPeriodicTimer(1, function () { static $count = 0; echo ++$count . "\n"; }); if ('failed') { // 問題発生 trigger_error("セットアップ中のエラー", E_USER_ERROR); // noticeやwarningでは実行停止しないのでダメ // または throw new \RuntimeException("セットアップ中のエラー"); } Loop::run();
この方法は自分でexitできないので任意の終了ステータスが指定できない。
もう一つは、最初にループを止めておく方法。
<?php use React\EventLoop\Loop; Loop::stop(); Loop::addPeriodicTimer(1, function () { static $count = 0; echo ++$count . "\n"; }); if ('failed') { // 問題発生 echo "セットアップ中のエラー\n"; exit(1); } Loop::run();
こちらは終了ステータスを指定できる。
そもそもイベントループの自動実行は必要なのだろうか?