###前提・実現したいこと
ReactPHPのevent-loopとpromiseを使って非同期処理のタイムアウトを実装したいです。
Webサーバはからまず、バッチ内のユーティリティメソッドで実装するつもりです。
###発生している問題・エラーメッセージ
$timeout_loop->addTimer(...);
$timeout_loop->run();
の順番に記述して実行すると、run()の次へ処理が進まず、addTimer()が完了するまで待ってしまう。
下記のソース1のvar_dumpを基準に言うと、現状ではA→B→C→F→Gとなり、
目的の処理であるD・Eを通らない。
問題解決のためaddPeriodicTimer()を使ったソース2を用意した。
非同期ならAAAA...BBBB...と出力されるはずだが、実際に実行すると、
A(1秒後)BA(1秒後)B...と非同期とは考えられない出力になった。
何か勘違いしてるはずなんだけど...
###ソース1
PHP
1<?php 2namespace Hoge; 3 4use React\EventLoop; 5use React\Promise; 6 7class Util 8{ 9 // タイムアウトつきでeval()の結果を返す。 10 public static function eval_with_timeout($code, $timeout_sec=10) 11 { 12 $result = FALSE; 13 $loop = EventLoop\Factory::create(); 14 $deferred = new Promise\Deferred(); 15var_dump('A:' . microtime(TRUE)); 16 17 // $timeout_sec秒を超えたらFALSEを返すことになる。 18 $timeout_loop = EventLoop\Factory::create(); 19 $timeout_loop->addTimer($timeout_sec, 20 function () use (&$deferred, &$loop) { 21var_dump('B:' . microtime(TRUE)); 22 $deferred->reject(); 23 $loop->stop(); 24var_dump('C:' . microtime(TRUE)); 25 }); 26 $timeout_loop->run(); 27 28 $promise = $deferred->promise()->then( 29 function () use ($code, &$result, &$timeout_loop) { 30var_dump('D:' . microtime(TRUE)); 31 $result = @eval($code); 32 if (is_null($result)) 33 { 34 $result = FALSE; 35 } 36 $timeout_loop->stop(); 37var_dump('E:' . microtime(TRUE)); 38 } 39 ); 40 $deferred->resolve(); 41 42var_dump('F:' . microtime(TRUE)); 43 $loop->run(); 44var_dump('G:' . microtime(TRUE)); 45 return $result; 46 } 47}
###ソース2
PHP
1$deferred = new Promise\Deferred(); 2$loop = EventLoop\Factory::create(); 3$timeout_sec = 0.1; 4$tick = 0.01; 5$elapsed = 0.0; 6$loop->addPeriodicTimer($tick, 7 function (EventLoop\Timer\Timer $timer) use ($loop, &$elapsed, $tick, $timeout_sec) { 8 $elapsed += $tick; 9 var_dump('A:' . microtime(TRUE) . ':' . $elapsed); 10 // 非同期ならAAAA...BBBB...と出力されるはず。 11 sleep(1); 12 var_dump('B:' . microtime(TRUE) . ':' . $elapsed); 13 if ($elapsed >= $timeout_sec) 14 { 15 $loop->cancelTimer($timer); 16 var_dump('C:' . microtime(TRUE)); 17 } 18}); 19$loop->run();
###お願い…
ReactPHPで使われる非同期処理については、
node.jsやCommonJSを扱ったことがないので基本的な理解が不足しているかもしれません。
JavaのAsyncTask、C#のTaskなら扱ったことがあります。
ReactPHPにこだわっているわけではないので、
他に分かりやすく目的を満たせるようなライブラリがあればそちらを使いたいです。
###補足情報(言語/FW/ツール等のバージョンなど)
PHP5.4 / ReactPHP最新版 / Windows
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。