Reactor Pattern and React @yuya_takeyama
Reactor Patternand
React@yuya_takeyama
How to parallelizePHP scripts?
どうやって PHP スクリプトを並列化させるか
There is more thanone wayto do it!やり方はいろいろある
exec()
foreach (range(1, 10) as $i) { exec("php script.php 1>&2 &");}echo "Hi", PHP_EOL;
pcntl_fork()echo getmypid() . ": I'm parent.", PHP_EOL;foreach (range(1, 10) as $i) { $pid = pcntl_fork(); if ($pid) { echo "{$pid}: I'm child.", PHP_EOL; exit; } pcntl_wait($status);}
proc_open()
stream
_set_b
lockin
g($str
eam, 0
)
proc_open()
stream
_set_b
lockin
g($str
eam, 0
)
proc_open()
stream_select()
stream
_set_b
lockin
g($str
eam, 0
)
proc_open()
popen()
stream_select()
stream
_set_b
lockin
g($str
eam, 0
)
proc_open()
popen()
system()
stream_select()
stream
_set_b
lockin
g($str
eam, 0
)
curl_multi_select()
proc_open()
popen()
system()
stream_select()
stream
_set_b
lockin
g($str
eam, 0
)
curl_multi_select()
proc_open()
popen()
system()
stream_select()
These arevery COMPLEX!
複雑過ぎる
It’s just like...
It’s just like...
What’s
?
• Event-driven
• non-blocking I/O
• with Pure PHP
• Native extensions are also availablefor better performance
var http = require('http');
http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World\n');}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');
<?phprequire __DIR__ . '/vendor/autoload.php';
$loop = new \React\EventLoop\StreamSelectLoop;
$socket = new \React\Socket\Server($loop);$server = new \React\Http\Server($socket);
$server->on('request', function ($req, $res) { $res->writeHead(200, ['Content-Type' => 'text/plain']); $res->end("Hello World\n");});
$socket->listen(1337);
echo "Server running at http://127.0.0.1:1337/", PHP_EOL;$loop->run();
How it works?
どうやって動くのか
\React\EventLoop
The Core of React
StreamSelectLoop
•stream_set_blocking($stream, 0)
•stream_select()
•ストリームをブロックしないモードにする
•I/O 待ちが発生しなくなる
stream_set_blocking($stream, 0)
stream_select()
select(2) for PHP
$ man 2 select
•複数のストリームを監視•準備ができたものの数を返す•準備ができたものたちを配列にセットする
stream_select()
複数のストリームを秒間何度もstream_select()
で監視し、準備ができたものから処理していくことで I/O 待ちのムダを軽減
複数のストリームを秒間何度もstream_select()
で監視し、準備ができたものから処理していくことで I/O 待ちのムダを軽減
ReactorPattern
• Stream
• Socket
• Http
• Dns
Components
• Whois
• ZMQ
• Predis/Async (Redis)
• Ratchet (Web Socket)
• Stream
• Socket
• Http
• Dns
Components
• Whois
• ZMQ
• Predis/Async (Redis)
• Ratchet (Web Socket)
• ChildProcess?
•Reactor パターンを使うとI/O処理を並列化/効率化できる
•React を使うと簡単に Reactor パターンの利点を享受できる
Conclusion
__halt_compiler();