Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
React (confoo)
Search
Igor Wiedler
March 01, 2013
Programming
850
7
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
React (confoo)
Igor Wiedler
March 01, 2013
More Decks by Igor Wiedler
See All by Igor Wiedler
Redis Bedtime Stories
igorw
1
380
Wide Event Analytics (LISA19)
igorw
4
950
a day in the life of a request
igorw
0
180
production: an owner's manual
igorw
0
200
The Power of 2
igorw
0
350
LISP 1.5 Programmer's Manual: A Dramatic Reading
igorw
0
490
The Moral Character of Software
igorw
1
330
interdisciplinary computing (domcode)
igorw
0
330
miniKanren (clojure berlin)
igorw
1
340
Other Decks in Programming
See All in Programming
デプロイ直後のレイテンシスパイクを調べたら、 Railsの仕様にたどり着いた
nhsykym
0
110
AIエージェント時代のコードレビューを設計する
nogu66
6
2.6k
AgentCore CLI で進化した AWS での AI エージェントの作り方 : 必要な機能を必要な時に
icoxfog417
PRO
2
260
Foundry Localでエージェント開発
seosoft
0
160
Intent as Code
shoppingjaws
4
660
数年滞っていたダークモード対応をおよそ2週間で完了させる
chigichan24
0
700
From 6 People Classroom Meetup to 100 People Regional Conference / FOSS4G Hiroshima 2026
furukawayasuto
0
130
GKE アップグレード前に知っておきたい Blue/Green と PDB の関係
stkk
0
160
App Storeの外へ──日本のiOSサイドローディング入門 for iOSDC Japan 2026
yuukiw00w
0
130
kubernetes コンポーネント開発入門 / 新卒N年目の勉強会&交流会!〜〇〇への誘い〜 #n_study
mazrean
0
180
型解析で実現する Go の言語内 DSL / Conference に Go! タイムテーブルの歩き方 for Gophers
mazrean
0
140
What We Talk About When We Talk About XP
m_seki
2
450
Featured
See All Featured
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
560
Pawsitive SEO: Lessons from My Dog (and Many Mistakes) on Thriving as a Consultant in the Age of AI
davidcarrasco
0
240
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
440
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
590
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
68
57k
The Pragmatic Product Professional
lauravandoore
37
7.4k
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.6k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
30k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
37
6.6k
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
270
Documentation Writing (for coders)
carmenintech
77
5.5k
Agile that works and the tools we love
rasmusluckow
331
22k
Transcript
None
Y U NO PHP?
@igorwesome
None
None
None
var http = require('http'); var server = new http.Server(); server.on('request',
function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World\n'); }); server.listen(1337, '127.0.0.1');
None
$server = stream_socket_server('tcp://127.0.0.1:1337'); while ($conn = stream_socket_accept($server, -1)) { fwrite($conn,
"HTTP/1.1 200 OK\r\n"); fwrite($conn, "Content-Length: 3\r\n\r\n"); fwrite($conn, "Hi\n"); fclose($conn); }
$s=stream_socket_server('tcp://[::1]:81'); while($c=stream_socket_accept($s,-1)) fwrite($c,"HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nHi");
Non-blocking I/O
C10K
Calculations are fast, I/O is slow.
Latency Comparison Numbers -------------------------- L1 cache reference 0.5 ns Branch
mispredict 5 ns L2 cache reference 7 ns Mutex lock/unlock 25 ns Main memory reference 100 ns Compress 1K bytes with Zippy 3,000 ns Send 1K bytes over 1 Gbps network 10,000 ns 0.01 ms Read 4K randomly from SSD* 150,000 ns 0.15 ms Read 1 MB sequentially from memory 250,000 ns 0.25 ms Round trip within same datacenter 500,000 ns 0.5 ms Read 1 MB sequentially from SSD* 1,000,000 ns 1 ms Disk seek 10,000,000 ns 10 ms Read 1 MB sequentially from disk 20,000,000 ns 20 ms Send packet CA->Netherlands->CA 150,000,000 ns 150 ms
Latency Comparison Numbers -------------------------- L1 cache reference 0.5 ns Branch
mispredict 5 ns L2 cache reference 7 ns Mutex lock/unlock 25 ns Main memory reference 100 ns Compress 1K bytes with Zippy 3,000 ns Send 1K bytes over 1 Gbps network 10,000 ns 0.01 ms Read 4K randomly from SSD* 150,000 ns 0.15 ms Read 1 MB sequentially from memory 250,000 ns 0.25 ms Round trip within same datacenter 500,000 ns 0.5 ms Read 1 MB sequentially from SSD* 1,000,000 ns 1 ms Disk seek 10,000,000 ns 10 ms Read 1 MB sequentially from disk 20,000,000 ns 20 ms Send packet CA->Netherlands->CA 150,000,000 ns 150 ms
None
stream_select
$readable = $read ?: null; $writable = $write ?: null;
$except = null; if (stream_select($readable, $writable, $except, 1)) { if ($readable) { foreach ($readable as $stream) { ... } } if ($writable) { foreach ($writable as $stream) { ... } } }
$readable = $read ?: null; $writable = $write ?: null;
$except = null; if (stream_select($readable, $writable, $except, 1)) { if ($readable) { foreach ($readable as $stream) { ... } } if ($writable) { foreach ($writable as $stream) { ... } } } Event Loop
None
None
Event-driven, non-blocking I/O with PHP.
Demo
$loop = React\EventLoop\Factory::create(); $socket = new React\Socket\Server($loop); $http = new
React\Http\Server($socket); $http->on('request', function ($req, $rep) { $rep->writeHead(); $rep->end("Hello World!\n"); }); $socket->listen(8080); $loop->run();
$loop = React\EventLoop\Factory::create(); $socket = new React\Socket\Server($loop); $socket->on('connection', function ($conn)
{ $conn->pipe($conn); }); $socket->listen(4000); $loop->run();
None
# composer.json { "require": { "react/http": "0.2.*" } }
$ composer install
Philosophy
Architecture
Événement EventEmitter for PHP
$emitter = new Evenement\EventEmitter(); $emitter->on('data', function ($data) { echo $data;
}); $emitter->emit('data', [$data]);
EventLoop Stream Socket Http
EventLoop $loop = React\EventLoop\Factory::create(); $server = stream_socket_server('tcp://127.0.0.1:8080'); stream_set_blocking($server, 0); $loop->addReadStream($server,
function ($server) use ($loop) { $conn = stream_socket_accept($server); ... });
EventLoop $loop->addPeriodicTimer(5, function () { $memory = memory_get_usage() / 1024;
$formatted = number_format($memory, 3).'K'; echo "Current memory usage: {$formatted}\n"; });
EventLoop $loop->run();
EventLoop backends stream_select libevent libev upcoming libuv
ReadableStream isReadable() pause() resume() close() Events data, end, error, close
Stream
ReadableStream isReadable() pause() resume() close() Events data, end, error, close
Stream
WritableStream isWritable() write($data) end($data) close() Events drain, error, close, pipe
Stream
WritableStream isWritable() write($data) end($data) close() Events drain, error, close, pipe
Stream
Stream $source = new React\Stream\Stream(fopen('omg.txt', 'r'), $loop); $dest = new
React\Stream\Stream(fopen('wtf.txt', 'w'), $loop); $source->pipe($dest);
Stream $a->pipe($b)->pipe($c); a | b | c
Socket $socket = new React\Socket\Server($loop); $socket->on('connection', function ($conn) { $conn->write("Hello
there!\n"); $conn->write("Welcome to this amazing server!\n"); $conn->write("Here's a tip: don't say anything.\n"); $conn->on('data', function ($data) use ($conn) { $conn->close(); }); }); $socket->listen(1337);
Http $socket = new React\Socket\Server($loop); $http = new React\Http\Server($socket); $http->on('request',
function ($request, $response) { $response->writeHead(200, ['Content-Type' => 'text/plain']); $response->end("Hello World!\n"); }); $socket->listen(1337);
EventLoop Stream Socket Http
Http HttpClient DNS
HttpClient Http DNS Stomp Whois
HttpClient Http DNS Stomp Whois WebSocket DNode SOCKS IRC
None
$foo->get(function ($bar) { $bar->get(function ($baz) { $baz->get(function ($bazinga) { $bazinga->get(function
() { throw new FuckItException(); }); }); }); });
async API (escaping callback hell)
React/Async
use React\Async\Util as Async; Async::waterfall([ function ($callback) use ($foo) {
$foo->get($callback); }, function ($bar, $callback) { $bar->get($callback); }, function ($baz, $callback) { $baz->get($callback); }, function ($bazinga, $callback) { $bazinga->get($callback); }, function ($callback) { throw new FuckItException(); } ]);
React/Promise
$dns ->resolve('igor.io') ->then(function ($ip) { echo "Host: $ip\n"; });
$promise ->then('doStuff') ->then('doMoreStuff') ->then('explosion') ->then(null, function ($e) { echo "[Error]
{$e->getMessage()}\n"; });
Deferred Promise Resolver Consumer Producer then() resolve() reject()
Streams
Readable Writable
Readable Writable Through
Readable Writable Through Composite
Buffered Sink
Bi-directional
conn logger parser $conn->pipe($inputLogger)->pipe($parser);
parser client $parser->on('message', function ($message) use ($client) { $client->say('pong'); });
client conn logger $client->pipe($outputLogger)->pipe($conn);
conn parser client conn
Houston we have a blocking call
Inter-process communication
React/ZMQ
$context = new React\ZMQ\Context($loop); $push = $context->getSocket(ZMQ::SOCKET_PUSH); $push->connect('tcp://127.0.0.1:5555'); $push->send('hello');
React/Stomp Predis/Async DNode-PHP
RealtimeWeb™
Ratchet
gifsockets!!!11
None
None
None
Questions? • joind.in/7969 • reactphp.org • @reactphp • @igorwesome
Questions? • joind.in/7969 • reactphp.org • @reactphp • @igorwesome
Http Server Worker Client Worker Worker Client Client HTTP