Slide 1

Slide 1 text

async php

Slide 2

Slide 2 text

disclaimers! ! ›❯ async is not commonplace ›❯ async requires work ›❯ hatters gonna hat

Slide 3

Slide 3 text

the problem! ! ›❯ scaling php from the inside is hard ›❯ persistent connections halt execution ›❯ synchronous core and history

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

asynchronous requests! ! http request hits server → then you ask for parsed input ! you get parsed input → then you ask for a database read ! ...

Slide 6

Slide 6 text

fixing the problem! ! ›❯ does it need to be fixed? ›❯ hardware is cheaper than developers

Slide 7

Slide 7 text

queues

Slide 8

Slide 8 text

queue daemons! ! ›❯ beanstalkd ›❯ rabbit mq

Slide 9

Slide 9 text

queue services! ! ›❯ amazon sqs ›❯ iron mq

Slide 10

Slide 10 text

›❯ 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

Slide 11

Slide 11 text

$queue = new Illuminate\Queue\Capsule\Manager(); ! $queue->addConnection([ "driver" => "beanstalkd", "host" => "localhost", "queue" => "default" ]); ! $queue->push("SendEmail",["message" => $message]);

Slide 12

Slide 12 text

class SendEmail { public function fire($job, $data) { // process the job // mark the job as handled with $job->release() } }

Slide 13

Slide 13 text

remember...! ! ›❯ queues are one-way ›❯ services have their quirks

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

gearman

Slide 16

Slide 16 text

gearman needs...! ! ›❯ a worker script ›❯ a manager daemon ›❯ a client script

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

›❯ 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

Slide 19

Slide 19 text

$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());

Slide 20

Slide 20 text

$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();

Slide 21

Slide 21 text

learn more! ! ›❯ gearman http://gearman.org ›❯ homebrew http://brew.sh ›❯ docs http://www.php.net/manual/en/book.gearman.php

Slide 22

Slide 22 text

react php

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

what react is not...! ! ›❯ react is not an external module ›❯ react is not a framework ›❯ react is not a magic bullet

Slide 25

Slide 25 text

›❯ 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

Slide 26

Slide 26 text

require("vendor/autoload.php"); $loop = React\EventLoop\Factory::create(); $socket = new React\Socket\Server($loop); $http = new React\Http\Server($socket, $loop);

Slide 27

Slide 27 text

$app = function($request, $response) { $response->writeHead(200, [ "Content-Type" => "text/html" ]); ! $response->end("hello world"); }; ! $http->on("request", $app);

Slide 28

Slide 28 text

$port = 8080; ! echo "Server at http://127.0.0.1:{$port}"; ! $socket->listen($port); $loop->run();

Slide 29

Slide 29 text

›❯ php "index.php" Server at http://127.0.0.1:8080 ! ›❯ curl -X GET "http://127.0.0.1:8080" hello world

Slide 30

Slide 30 text

remember...! ! ›❯ the server is a long-running script ›❯ unhandled exceptions and fatal errors kill it ›❯ timeouts do not apply ›❯ cli php.ini is used

Slide 31

Slide 31 text

routes! ! ›❯ download a router ›❯ define routes ›❯ dispatch requests

Slide 32

Slide 32 text

›❯ 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

Slide 33

Slide 33 text

function show($request, $response, $parameters) { $response->end("showing"); } ! function save($request, $response, $parameters) { $response->end("saving"); }

Slide 34

Slide 34 text

$dispatcher = FastRoute\simpleDispatcher( function(FastRoute\RouteCollector $collector) { $collector->addRoute("GET", "/products", "show"); $collector->addRoute("POST", "/products", "save"); } );

Slide 35

Slide 35 text

$app = function($request, $response) use ($dispatcher) { ! $route = $dispatcher->dispatch( $request->getMethod(), $request->getPath() );

Slide 36

Slide 36 text

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;

Slide 37

Slide 37 text

case FastRoute\Dispatcher::FOUND: $response->writeHead(200, [ "Content-Type" => "text/html" ]); ! call_user_func_array($route[1], [ $request, $response, $route[2] ]); ! break;

Slide 38

Slide 38 text

›❯ curl -X GET "http://127.0.0.1:8080/products" showing ! ›❯ curl -X POST "http://127.0.0.1:8080/products" saving

Slide 39

Slide 39 text

sockets! ! ›❯ download ratchet ›❯ implement MessageComponentInterface ›❯ pass your subclass to Http\Server

Slide 40

Slide 40 text

›❯ 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

Slide 41

Slide 41 text

use Ratchet\ConnectionInterface; use Ratchet\MessageComponentInterface; ! class Chat extends React\Socket\Server implements MessageComponentInterface { }

Slide 42

Slide 42 text

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);

Slide 43

Slide 43 text

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"});

Slide 44

Slide 44 text

public function onOpen(ConnectionInterface $socket) { $this->socket->send("connected"); } ! public function onMessage(ConnectionInterface $socket, $message) { $this->socket->send("message: {$message}"); }

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

why bother?

Slide 47

Slide 47 text

high concurrency! ! ›❯ theoretically... ›❯ higher concurrency != faster

Slide 48

Slide 48 text

socket programming! ! ›❯ web sockets http://www.html5rocks.com/en/tutorials/websockets/basics ›❯ socket chat tutorial https://medium.com/laravel-4/eaa550829538

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

thanks! ! ›❯ follow http://twitter.com/followchrisp ›❯ learn http://tutorials.io