$30 off During Our Annual Pro Sale. View Details »

Async PHP (Sunshine)

Async PHP (Sunshine)

PHP has emerged from it’s dark past; just in time to learn from the advances in event-based programming languages/platforms. As a result; there is vast, untapped potential in developing event-based, real-time applications. Utilising emerging open-source projects, PHP developers can join the party.

Christopher Pitt

February 06, 2016
Tweet

More Decks by Christopher Pitt

Other Decks in Programming

Transcript

  1. async php

    View Slide

  2. thanks
    sunshine

    View Slide

  3. thanks
    silverstripe

    View Slide

  4. story 'me

    View Slide

  5. you can write
    async code

    View Slide

  6. spreading work to
    other threads

    View Slide

  7. forking

    View Slide

  8. $pid = pcntl_fork();
    if ($pid) {
    // you're in the parent process
    pcntl_waitpid($pid, $status, WUNTRACED);
    if ($status > 0) {
    // handle the error
    }
    } else {
    // do something in the child process
    if ($failed) {
    exit(1);
    }
    exit(0);
    }

    View Slide

  9. php.net/manual/en/book.pcntl.php

    View Slide

  10. leanpub.com/signalingphp

    View Slide

  11. threading

    View Slide

  12. class MyThread extends Thread
    {
    public $hasLicense = null;
    private $repository;
    public function __construct($repository)
    {
    $this->repository = escapeshellarg($repository);
    }
    public function run()
    {
    $folder = hash("sha256", $this->repository);
    exec("git clone " . $this->repository . " " . $folder);
    chdir(__DIR__ . "/" . $folder);
    $this->hasLicense = preg_grep("/^LICENSE/i", glob("*"));
    }
    }

    View Slide

  13. $thread = new MyThread("[email protected]:php/php-src.git");
    if ($thread->start()) {
    $thread->join();
    // do something with $thread->hasLicense
    }

    View Slide

  14. php.net/manual/en/book.pthreads.php

    View Slide

  15. pthreads.org

    View Slide

  16. spreading the work
    to other machines

    View Slide

  17. message queues

    View Slide

  18. $pheanstalk = new Pheanstalk\Pheanstalk("127.0.0.1");
    $pheanstalk->useTube("sunshine")->put("a message");
    // some time later...
    $message = $pheanstalk->watch("sunshine")->reserve();
    $pheanstalk->delete($message);

    View Slide

  19. $context = new ZMQContext();
    $socket = new ZMQSocket($context, ZMQ::SOCKET_PUSH);
    $socket->connect("tcp://127.0.0.1:5555");
    $socket->send("a message");
    // some time later
    $socket = new ZMQSocket($context, ZMQ::SOCKET_PULL);
    $socket->bind("tcp://127.0.0.1:5555");
    $message = $socket->recv();

    View Slide

  20. you can also use rabbit mq,
    amazon sqs, and iron mq

    View Slide

  21. gearman

    View Slide

  22. $client = new GearmanClient();
    $client->addServer("127.0.0.1", 4730);
    $client->setCompleteCallback(function(GearmanTask $task) {
    // so domething when the task is complete
    });
    $task = $client->addTask("inspect", "some data");
    $client->runTasks();

    View Slide

  23. $worker = new GearmanWorker();
    $worker->addServer("127.0.0.1", 4730);
    $worker->addFunction("inspect", function(GearmanJob $job) {
    // do the job, with $job->workload()
    });
    while ($worker->work()) {
    if ($worker->returnCode() !== GEARMAN_SUCCESS) {
    // something went wrong
    }
    }

    View Slide

  24. php.net/manual/en/book.gearman.php

    View Slide

  25. async standard library

    View Slide

  26. amphp, icicle, react...

    View Slide

  27. explicit event loops

    View Slide

  28. use Icicle\Http\Message\BasicResponse;
    use Icicle\Http\Message\Request;
    use Icicle\Http\Server\RequestHandler;
    use Icicle\Socket\Socket;
    use Icicle\Stream\MemorySink;
    class MyRequestHandler implements RequestHandler
    {
    public function onRequest(Request $request, Socket $socket): Generator
    {
    $stream = new MemorySink();
    yield from $stream->end("hello world");
    yield new BasicResponse(200, [
    "Content-Type" => "text/plain",
    "Content-Length" => $stream->getLength(),
    ], $stream);
    }
    public function onError(int $code, Socket $socket): Generator
    {
    yield new BasicResponse($code);
    }
    }

    View Slide

  29. use Icicle\Http\Server\Server;
    use Icicle\Loop;
    $server = new Server(new MyRequestHandler());
    $server->listen(81, "127.0.0.1");
    $server->listen(82, "127.0.0.1");
    Loop\run();

    View Slide

  30. server {
    listen 80;
    server_name acme.com;
    location / {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header Host $http_host;
    proxy_pass http://127.0.0.1:81;
    }
    }

    View Slide

  31. use Icicle\Http\Message\Request;
    use Icicle\Http\Message\Response;
    use Icicle\Socket\Socket;
    use Icicle\WebSocket\Application;
    use Icicle\WebSocket\Connection;
    use Icicle\WebSocket\Message;
    class MyApplication implements Application
    {
    public function onHandshake(Response $response, Request $request, Socket $socket): Generator
    {
    yield $response;
    }
    public function onConnection(Connection $connection): Generator
    {
    $iterator = $connection->read()->getIterator();
    while (yield $iterator->isValid()) {
    // $iterator->getCurrent() + $connection->send(new Message())
    }
    $connection->close();
    }
    }

    View Slide

  32. use Icicle\Http\Message\BasicResponse;
    use Icicle\Http\Message\Request;
    use Icicle\Http\Server\RequestHandler;
    use Icicle\Socket\Socket;
    use Icicle\WebSocket\Application;
    use Icicle\WebSocket\Server\Server;
    class MyRequestHandler implements RequestHandler
    {
    private $application;
    public function __construct(Application $application)
    {
    $this->application = $application;
    }
    public function onRequest(Request $request, Socket $socket): Generator
    {
    yield $this->application;
    }
    public function onError($code, Socket $socket): Generator
    {
    yield new BasicResponse($code);
    }
    }
    $server = new Server(new MyRequestHandler(new MyApplication()));

    View Slide

  33. 1. corou'nes
    2. promises + observables
    3. streams
    4. filesystem
    5. dns
    6. threading + forking

    View Slide

  34. icicle.io/docs

    View Slide

  35. examples

    View Slide

  36. github.com/asyncphp

    View Slide

  37. why [i think] you should
    try async

    View Slide

  38. value for you

    View Slide

  39. value for the community

    View Slide

  40. I don't get why people can't deal
    with async environments. Cause, for
    me, it's like the dream.
    — @dead_lugosi

    View Slide

  41. want to know more
    about this stuff?

    View Slide

  42. assertchris.io/asyncphp

    View Slide

  43. If I said to you in 2000 that one day
    PHP would have any kind of strict
    mode, you would have laughed in
    my face.

    View Slide

  44. It isn't the year 2000 any more ... it's
    nature is, to a large degree, dictated
    by RFCs that pass the vote ...

    View Slide

  45. And while you will hear people use
    it's nature to argue against certain
    features, those voices aren't enough
    to stand in the way of progress.
    — @krakjoe

    View Slide

  46. joind.in/talk/84ad6

    View Slide

  47. thanks!
    twi$er.com/assertchris

    View Slide