Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Async PHP Redux
Search
Christopher Pitt
May 08, 2014
Technology
2
550
Async PHP Redux
Christopher Pitt
May 08, 2014
Tweet
Share
More Decks by Christopher Pitt
See All by Christopher Pitt
Making Robots (PHP Unicorn Conf)
chrispitt
1
130
Transforming Magento (NomadMage 2017)
chrispitt
2
72
Forget What You Know
chrispitt
1
120
Monads In PHP → php[tek]
chrispitt
3
410
Breaking The Enigma → php[tek]
chrispitt
0
120
Turn on the Generator!
chrispitt
0
140
Implementing Languages (FluentConf)
chrispitt
1
300
Async PHP (Sunshine)
chrispitt
0
380
Helpful Robot
chrispitt
0
87
Other Decks in Technology
See All in Technology
レガシーをぶっ壊せ。AEONで始めるDevRelの話 / Qiita Night 2024-2-22
aeonpeople
3
1.2k
AWS認定資格を取得したので、初めてマネコンを触った時を振り返ってみた。
ainatsuptr
2
100
アクセシビリティを考慮したUI/CSSフレームワーク・ライブラリ選定
yajihum
2
990
プロデザ! BY リクルート vol.18_リクルートのリサーチ実践組織「リサーチブーストコミュニティ」
recruitengineers
PRO
3
270
KubeCon EU 2024 Recap “Kubernetes Policy Time Machine: Where to Next?”
ryysud
0
190
継続的な改善 x ⾮連続的な進化
sansantech
PRO
3
130
Azure犬駆動開発の記録/GlobalAzureFukuoka2024_20240420
nina01
1
180
Meta Quest 3 で動く桜マシマシ WebXR アプリを IBM Cloud Code Engine と Babylon.js で作った話
1ftseabass
PRO
0
120
Postman v10リリース後を振り返る
nagix
0
170
ChatworkのSRE部って実は 半分くらいPlatform Engineering部かもしれない
saramune
0
150
サーバー間 GraphQL と webmock-graphql の話 / server-to-server graphql and webmock-graphql
qsona
2
170
FrontDoorとWebAppsを組み合わせた際のリダイレクト処理の注意点
kenichirokimura
1
470
Featured
See All Featured
The Illustrated Children's Guide to Kubernetes
chrisshort
30
46k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
240
1.2M
Java REST API Framework Comparison - PWX 2021
mraible
PRO
18
6.9k
Visualization
eitanlees
135
14k
Docker and Python
trallard
33
2.7k
Fantastic passwords and where to find them - at NoRuKo
philnash
36
2.5k
What's in a price? How to price your products and services
michaelherold
237
11k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
226
16k
How to name files
jennybc
64
93k
Designing with Data
zakiwarfel
95
4.8k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
352
28k
Stop Working from a Prison Cell
hatefulcrawdad
266
19k
Transcript
async php
disclaimers! ! ›❯ async is not commonplace ›❯ async requires
work ›❯ hatters gonna hat
the problem! ! ›❯ scaling php from the inside is
hard ›❯ persistent connections halt execution ›❯ synchronous core and history
synchronous requests! ! http request hits server → then you
parse input → then you read the database → then you render the view → then you return the response
asynchronous requests! ! http request hits server → then you
ask for parsed input ! you get parsed input → then you ask for a database read ! ...
fixing the problem! ! ›❯ does it need to be
fixed? ›❯ hardware is cheaper than developers
queues
queue daemons! ! ›❯ beanstalkd ›❯ rabbit mq
queue services! ! ›❯ amazon sqs ›❯ iron mq
›❯ composer require "illuminate/queue:4.1.0" ./composer.json has been updated Loading composer
repositories with package information Updating dependencies (including require-dev) - Installing symfony/process (v2.4.4) Loading from cache
$queue = new Illuminate\Queue\Capsule\Manager(); ! $queue->addConnection([ "driver" => "beanstalkd", "host"
=> "localhost", "queue" => "default" ]); ! $queue->push("SendEmail",["message" => $message]);
class SendEmail { public function fire($job, $data) { // process
the job // mark the job as handled with $job->release() } }
remember...! ! ›❯ queues are one-way ›❯ services have their
quirks
learn more! ! ›❯ queues in laravel http://laravel.com/docs/queues ›❯ illuminate/queue
https://github.com/illuminate/queue ›❯ beanstalkd http://kr.github.io/beanstalkd ›❯ rabbit mq https://www.rabbitmq.com ›❯ iron mq http://www.iron.io/mq ›❯ amazon sqs https://aws.amazon.com/sqs
gearman
gearman needs...! ! ›❯ a worker script ›❯ a manager
daemon ›❯ a client script
how it works! ! client connects to daemon → then
client adds task to queue → then daemon sends task to worker → then worker processes task → then worker sends result to daemon → then daemon sends result to client
›❯ brew install gearmand ==> Downloading https://launchpad.net/gearmand/1.2/1.1.9/+download/ gearmand-1.1.9.tar.gz Already downloaded:
/Library/Caches/Homebrew/gearman-1.1.9.tar.gz ==> Patching patching file libgearman-1.0/gearman.h ! ›❯ /usr/local/sbin/gearmand -d
$worker = new GearmanWorker(); $worker->addServer(); ! $worker->addFunction("handle", function($job) { //
get the job data with $job->workload() // mark the job as handled with $job->handle() // return the result }); ! while ($worker->work());
$client = new GearmanClient(); $client->addServer(); ! $client->setCompleteCallback(function($task) { // get
the result data with $task->data() }); ! $task = $client->addTask("handle", "the task data"); $client->runTasks();
learn more! ! ›❯ gearman http://gearman.org ›❯ homebrew http://brew.sh ›❯
docs http://www.php.net/manual/en/book.gearman.php
react php
what react is...! ! ›❯ react is a replacement for
plain old php + apache ›❯ react is like the php equivalent of node js ›❯ react is still beta
what react is not...! ! ›❯ react is not an
external module ›❯ react is not a framework ›❯ react is not a magic bullet
›❯ composer require "react/react:0.4.0" ./composer.json has been updated Loading composer
repositories with package information Updating dependencies (including require-dev) - Installing react/promise (v2.0.0) Loading from cache
require("vendor/autoload.php"); $loop = React\EventLoop\Factory::create(); $socket = new React\Socket\Server($loop); $http =
new React\Http\Server($socket, $loop);
$app = function($request, $response) { $response->writeHead(200, [ "Content-Type" => "text/html"
]); ! $response->end("hello world"); }; ! $http->on("request", $app);
$port = 8080; ! echo "Server at http://127.0.0.1:{$port}"; ! $socket->listen($port);
$loop->run();
›❯ php "index.php" Server at http://127.0.0.1:8080 ! ›❯ curl -X
GET "http://127.0.0.1:8080" hello world
remember...! ! ›❯ the server is a long-running script ›❯
unhandled exceptions and fatal errors kill it ›❯ timeouts do not apply ›❯ cli php.ini is used
routes! ! ›❯ download a router ›❯ define routes ›❯
dispatch requests
›❯ composer require "nikic/fast-route:dev-master" ./composer.json has been updated Loading composer
repositories with package information Updating dependencies (including require-dev) - Installing nikic/fast-route (dev-master 29c5bf7) Cloning 29c5bf70254d8ce59414646de3e9e43aafc9735e
function show($request, $response, $parameters) { $response->end("showing"); } ! function save($request,
$response, $parameters) { $response->end("saving"); }
$dispatcher = FastRoute\simpleDispatcher( function(FastRoute\RouteCollector $collector) { $collector->addRoute("GET", "/products", "show"); $collector->addRoute("POST",
"/products", "save"); } );
$app = function($request, $response) use ($dispatcher) { ! $route =
$dispatcher->dispatch( $request->getMethod(), $request->getPath() );
switch($route[0]) { case FastRoute\Dispatcher::NOT_FOUND: // ... 404 Not Found break;
! case FastRoute\Dispatcher::METHOD_NOT_ALLOWED: $allowedMethods = $route[1]; // ... 405 Method Not Allowed break;
case FastRoute\Dispatcher::FOUND: $response->writeHead(200, [ "Content-Type" => "text/html" ]); ! call_user_func_array($route[1],
[ $request, $response, $route[2] ]); ! break;
›❯ curl -X GET "http://127.0.0.1:8080/products" showing ! ›❯ curl -X
POST "http://127.0.0.1:8080/products" saving
sockets! ! ›❯ download ratchet ›❯ implement MessageComponentInterface ›❯ pass
your subclass to Http\Server
›❯ composer require "cboden/ratchet:0.3.0" ./composer.json has been updated Loading composer
repositories with package information Updating dependencies (including require-dev) - Installing symfony/routing (v2.4.4) Loading from cache ! - Installing symfony/http-foundation (v2.4.4) Loading from cache
use Ratchet\ConnectionInterface; use Ratchet\MessageComponentInterface; ! class Chat extends React\Socket\Server implements
MessageComponentInterface { }
require("vendor/autoload.php"); $loop = React\EventLoop\Factory::create(); // $socket = new React\Socket\Server($loop); $socket
= new Chat($loop); $http = new React\Http\Server($socket, $loop);
var socket = new WebSocket("ws://127.0.0.1:8080"); ! socket.addEventListener("message", function(e) { console.log(JSON.parse(e.data));
}); ! socket.send(JSON.stringify({"foo" : "bar"});
public function onOpen(ConnectionInterface $socket) { $this->socket->send("connected"); } ! public function
onMessage(ConnectionInterface $socket, $message) { $this->socket->send("message: {$message}"); }
learn more! ! ›❯ composer https://getcomposer.org ›❯ installing react php
https://github.com/reactphp/react#install ›❯ learning react php http://reactphp.org ›❯ learning ratchet http://socketo.me
why bother?
high concurrency! ! ›❯ theoretically... ›❯ higher concurrency != faster
socket programming! ! ›❯ web sockets http://www.html5rocks.com/en/tutorials/websockets/basics ›❯ socket chat
tutorial https://medium.com/laravel-4/eaa550829538
something new! ! ›❯ learning new language paradigms is great
›❯ event-based code may make cleaner code ›❯ async is useful and is being used in popular frameworks
thanks! ! ›❯ follow http://twitter.com/followchrisp ›❯ learn http://tutorials.io