Upgrade to Pro — share decks privately, control downloads, hide ads and more …

PCS2020 - PHP Além do Síncrono

Diana Arnos
September 12, 2020

PCS2020 - PHP Além do Síncrono

Apresentada durante o PHP Community Summit de 2020.

Quando tudo era mato, ninguém acreditava que a linguagem PHP poderia ser usada para nada além da execução de scripts simples, sites ou um CMS de código bem bagunçado.
Então o mundo mudou e hoje temos grandes frameworks, sistemas corporativos, grandes portais e redes sociais e até sistemas de segurança e pagamentos escritos em PHP.
Agora, a comunidade se debruça sobre o novo hype (ou seria necessidade?): processamento assíncrono e paralelo.
Nessa apresentação, vamos entender a difereça entre async e paralelo, como podemos trabalhar com isso usando PHP (inclusive nativamente) e quais as principais diferenças entre as soluções mais hypadas (digo, famosas) do momento.

Diana Arnos

September 12, 2020
Tweet

More Decks by Diana Arnos

Other Decks in Programming

Transcript

  1. PHP Além do Síncrono
    O reino mágico do processamento async e paralelo

    View Slide

  2. @dianaarnos
    Dev, Sec, Music, Kung Fu.
    PHP Engineer @ Usabilla (Amsterdã, Holanda) (soon)
    Evangelista @ PHPSP
    Evangelista @ PHPWomenBR

    View Slide

  3. View Slide

  4. PHP é síncrono

    View Slide

  5. PHP é síncrono
    Mas dá pra trabalhar
    assíncrono

    View Slide

  6. PHP é síncrono
    Mas dá pra trabalhar
    assíncrono
    Não é pra isso
    que serve!

    View Slide

  7. PHP é síncrono
    Mas dá pra trabalhar
    assíncrono
    Não é pra isso
    que serve!
    Se funciona,
    então serve

    View Slide

  8. PHP é síncrono
    Mas dá pra trabalhar
    assíncrono
    Não é pra isso
    que serve!
    Se funciona,
    então serve
    M
    AS
    E
    O
    SHARE
    NOTHING?!

    View Slide

  9. PHP é síncrono
    Mas dá pra trabalhar
    assíncrono
    Não é pra isso
    que serve!
    Se funciona,
    então serve
    M
    AS
    E
    O
    SHARE
    NOTHING?!
    M
    AS
    É
    O
    UTRO
    CO
    NTEXTO
    !

    View Slide

  10. View Slide

  11. Calma, xovem. É muita emoção.

    View Slide

  12. View Slide

  13. Síncrono
    Requests
    Tempo
    Task #1
    Task #2
    Task #3

    View Slide

  14. Assíncrono
    Requests
    Tempo
    Task #1
    Task #2
    Task #3
    Task #1
    Task #3

    View Slide

  15. Paralelo
    Requests
    Tempo
    Task #1
    Task #2
    Task #3
    Task #1
    Task #3
    Task #2
    Task #1
    Task #2
    Task #3

    View Slide

  16. Paralelismo e Assíncronismo = Concorrência

    View Slide

  17. Concorrência no PHP?

    View Slide

  18. View Slide

  19. View Slide

  20. View Slide

  21. Ext Parallel

    View Slide

  22. Ext Parallel - ZTS

    View Slide

  23. use parallel\Runtime;
    $runtime = new Runtime();
    $future = $runtime->run(function(){
    for ($i = 0; $i < 100; $i++)
    echo "*";
    return "fácil";
    });
    for ($i = 0; $i < 100; $i++) {
    echo ".";
    }
    printf("\nUsar o \\parallel\\Runtime é %s\n", $future->value());

    View Slide

  24. Parallel x Swoole
    Swoole implements co-operative multi-tasking, and if you were following along, you
    already figured out that this is not based on parallel concurrency, but on
    asynchronous concurrency. When the readme says "you can think of co-routines as
    individual threads", it's referring to green threads. No user code is executed in
    parallel, it is executed asynchronously. The internals of swoole does use threads
    but to service I/O, not to execute user code.
    - Joe Watkins (krakjoe)

    View Slide

  25. PHP é síncrono. Realmente.

    View Slide

  26. echo PHP_EOL . "Step 1" . PHP_EOL;
    for ($i = 0; $i <11; $i++) {
    echo ".";
    }
    echo PHP_EOL . "Step 2" . PHP_EOL;
    for ($i = 0; $i <11; $i++) {
    echo ".";
    }
    echo PHP_EOL . "Finish." . PHP_EOL;

    View Slide

  27. echo PHP_EOL . "Step 1" . PHP_EOL;
    for ($i = 0; $i <11; $i++) {
    echo ".";
    }
    echo PHP_EOL . "Step 2" . PHP_EOL;
    for ($i = 0; $i <11; $i++) {
    echo ".";
    }
    echo PHP_EOL . "Finish." . PHP_EOL;

    View Slide

  28. echo PHP_EOL . "Step 1" . PHP_EOL;
    for ($i = 0; $i <11; $i++) {
    echo ".";
    }
    echo PHP_EOL . "Step 2" . PHP_EOL;
    for ($i = 0; $i <11; $i++) {
    echo ".";
    }
    echo PHP_EOL . "Finish." . PHP_EOL;

    View Slide

  29. echo PHP_EOL . "Step 1" . PHP_EOL;
    for ($i = 0; $i <11; $i++) {
    echo ".";
    }
    echo PHP_EOL . "Step 2" . PHP_EOL;
    for ($i = 0; $i <11; $i++) {
    echo ".";
    }
    echo PHP_EOL . "Finish." . PHP_EOL;

    View Slide

  30. echo PHP_EOL . "Step 1" . PHP_EOL;
    for ($i = 0; $i <11; $i++) {
    echo ".";
    }
    echo PHP_EOL . "Step 2" . PHP_EOL;
    for ($i = 0; $i <11; $i++) {
    echo ".";
    }
    echo PHP_EOL . "Finish." . PHP_EOL;

    View Slide

  31. echo PHP_EOL . "Step 1" . PHP_EOL;
    for ($i = 0; $i <11; $i++) {
    echo ".";
    }
    echo PHP_EOL . "Step 2" . PHP_EOL;
    for ($i = 0; $i <11; $i++) {
    echo ".";
    }
    echo PHP_EOL . "Finish." . PHP_EOL;

    View Slide

  32. echo PHP_EOL . "Step 1" . PHP_EOL;
    for ($i = 0; $i <11; $i++) {
    echo ".";
    }
    echo PHP_EOL . "Step 2" . PHP_EOL;
    for ($i = 0; $i <11; $i++) {
    echo ".";
    }
    echo PHP_EOL . "Finish." . PHP_EOL;

    View Slide

  33. Mas dá pra ser assíncrono também.

    View Slide

  34. Mas dá pra ser assíncrono também.
    Nativo.

    View Slide

  35. View Slide

  36. Olá, generators!

    View Slide

  37. $function = function ()
    {
    yield PHP_EOL . "Starting";
    echo PHP_EOL . "-";
    yield PHP_EOL . ".";
    $incoming = yield;
    echo PHP_EOL . $incoming;
    return PHP_EOL . "Generator's end."
    ;
    };

    View Slide

  38. $generator = $function();
    echo PHP_EOL . "Main flow";
    echo $generator->current();
    echo PHP_EOL . "Main flow";
    $generator->next();
    echo $generator->current();
    $generator->next();
    echo PHP_EOL . "Main flow";
    $generator->send("aeeewww");
    $generator->next();
    echo $generator->getReturn() . PHP_EOL;
    echo PHP_EOL . "Main flow";
    $function = function ()
    {
    yield PHP_EOL . "Starting";
    echo PHP_EOL . "-";
    yield PHP_EOL . ".";
    $incoming = yield;
    echo PHP_EOL . $incoming;
    return PHP_EOL . "Generator's end."
    ;
    };

    View Slide

  39. $function = function ()
    {
    yield PHP_EOL . "Starting";
    echo PHP_EOL . "-";
    yield PHP_EOL . ".";
    $incoming = yield;
    echo PHP_EOL . $incoming;
    return PHP_EOL .
    "Generator's end.";
    };
    $generator = $function();
    echo PHP_EOL . "Main flow" ;
    echo $generator->current();
    echo PHP_EOL . "Main flow" ;
    $generator->next();
    echo $generator->current();
    $generator->next();
    echo PHP_EOL . "Main flow" ;
    $generator->send("aeeewww");
    $generator->next();
    echo $generator->getReturn() .
    PHP_EOL;
    echo PHP_EOL . "Main flow" ;

    View Slide

  40. $function = function ()
    {
    yield PHP_EOL . "Starting";
    echo PHP_EOL . "-";
    yield PHP_EOL . ".";
    $incoming = yield;
    echo PHP_EOL . $incoming;
    return PHP_EOL .
    "Generator's end.";
    };
    $generator = $function();
    echo PHP_EOL . "Main flow" ;
    echo $generator->current();
    echo PHP_EOL . "Main flow" ;
    $generator->next();
    echo $generator->current();
    $generator->next();
    echo PHP_EOL . "Main flow" ;
    $generator->send("aeeewww");
    $generator->next();
    echo $generator->getReturn() .
    PHP_EOL;
    echo PHP_EOL . "Main flow" ;

    View Slide

  41. $generator = $function();
    echo PHP_EOL . "Main flow" ;
    echo $generator->current();
    echo PHP_EOL . "Main flow" ;
    $generator->next();
    echo $generator->current();
    $generator->next();
    echo PHP_EOL . "Main flow" ;
    $generator->send("aeeewww");
    $generator->next();
    echo $generator->getReturn() .
    PHP_EOL;
    echo PHP_EOL . "Main flow" ;
    $function = function ()
    {
    yield PHP_EOL . "Starting";
    echo PHP_EOL . "-";
    yield PHP_EOL . ".";
    $incoming = yield;
    echo PHP_EOL . $incoming;
    return PHP_EOL .
    "Generator's end.";
    };

    View Slide

  42. $generator = $function();
    echo PHP_EOL . "Main flow" ;
    echo $generator->current();
    echo PHP_EOL . "Main flow" ;
    $generator->next();
    echo $generator->current();
    $generator->next();
    echo PHP_EOL . "Main flow" ;
    $generator->send("aeeewww");
    $generator->next();
    echo $generator->getReturn() .
    PHP_EOL;
    echo PHP_EOL . "Main flow" ;
    $function = function ()
    {
    yield PHP_EOL . "Starting";
    echo PHP_EOL . "-";
    yield PHP_EOL . ".";
    $incoming = yield;
    echo PHP_EOL . $incoming;
    return PHP_EOL .
    "Generator's end.";
    };

    View Slide

  43. $generator = $function();
    echo PHP_EOL . "Main flow" ;
    echo $generator->current();
    echo PHP_EOL . "Main flow" ;
    $generator->next();
    echo $generator->current();
    $generator->next();
    echo PHP_EOL . "Main flow" ;
    $generator->send("aeeewww");
    $generator->next();
    echo $generator->getReturn() .
    PHP_EOL;
    echo PHP_EOL . "Main flow" ;
    $function = function ()
    {
    yield PHP_EOL . "Starting";
    echo PHP_EOL . "-";
    yield PHP_EOL . ".";
    $incoming = yield;
    echo PHP_EOL . $incoming;
    return PHP_EOL .
    "Generator's end.";
    };

    View Slide

  44. $generator = $function();
    echo PHP_EOL . "Main flow" ;
    echo $generator->current();
    echo PHP_EOL . "Main flow" ;
    $generator->next();
    echo $generator->current();
    $generator->next();
    echo PHP_EOL . "Main flow" ;
    $generator->send("aeeewww");
    $generator->next();
    echo $generator->getReturn() .
    PHP_EOL;
    echo PHP_EOL . "Main flow" ;
    $function = function ()
    {
    yield PHP_EOL . "Starting";
    echo PHP_EOL . "-";
    yield PHP_EOL . ".";
    $incoming = yield;
    echo PHP_EOL . $incoming;
    return PHP_EOL .
    "Generator's end.";
    };

    View Slide

  45. $generator = $function();
    echo PHP_EOL . "Main flow" ;
    echo $generator->current();
    echo PHP_EOL . "Main flow" ;
    $generator->next();
    echo $generator->current();
    $generator->next();
    echo PHP_EOL . "Main flow" ;
    $generator->send("aeeewww");
    $generator->next();
    echo $generator->getReturn() .
    PHP_EOL;
    echo PHP_EOL . "Main flow" ;
    $function = function ()
    {
    yield PHP_EOL . "Starting";
    echo PHP_EOL . "-";
    yield PHP_EOL . ".";
    $incoming = yield;
    echo PHP_EOL . $incoming;
    return PHP_EOL .
    "Generator's end.";
    };

    View Slide

  46. $generator = $function();
    echo PHP_EOL . "Main flow" ;
    echo $generator->current();
    echo PHP_EOL . "Main flow" ;
    $generator->next();
    echo $generator->current();
    $generator->next();
    echo PHP_EOL . "Main flow" ;
    $generator->send("aeeewww");
    $generator->next();
    echo $generator->getReturn() .
    PHP_EOL;
    echo PHP_EOL . "Main flow" ;
    $function = function ()
    {
    yield PHP_EOL . "Starting";
    echo PHP_EOL . "-";
    yield PHP_EOL . ".";
    $incoming = yield;
    echo PHP_EOL . $incoming;
    return PHP_EOL .
    "Generator's end.";
    };

    View Slide

  47. $generator = $function();
    echo PHP_EOL . "Main flow" ;
    echo $generator->current();
    echo PHP_EOL . "Main flow" ;
    $generator->next();
    echo $generator->current();
    $generator->next();
    echo PHP_EOL . "Main flow" ;
    $generator->send("aeeewww");
    $generator->next();
    echo $generator->getReturn() .
    PHP_EOL;
    echo PHP_EOL . "Main flow" ;
    $function = function ()
    {
    yield PHP_EOL . "Starting";
    echo PHP_EOL . "-";
    yield PHP_EOL . ".";
    $incoming = yield;
    echo PHP_EOL . $incoming;
    return PHP_EOL .
    "Generator's end.";
    };

    View Slide

  48. $generator = $function();
    echo PHP_EOL . "Main flow" ;
    echo $generator->current();
    echo PHP_EOL . "Main flow" ;
    $generator->next();
    echo $generator->current();
    $generator->next();
    echo PHP_EOL . "Main flow" ;
    $generator->send("aeeewww");
    $generator->next();
    echo $generator->getReturn() .
    PHP_EOL;
    echo PHP_EOL . "Main flow" ;
    $function = function ()
    {
    yield PHP_EOL . "Starting";
    echo PHP_EOL . "-";
    yield PHP_EOL . ".";
    $incoming = yield;
    echo PHP_EOL . $incoming;
    return PHP_EOL .
    "Generator's end.";
    };

    View Slide

  49. $generator = $function();
    echo PHP_EOL . "Main flow" ;
    echo $generator->current();
    echo PHP_EOL . "Main flow" ;
    $generator->next();
    echo $generator->current();
    $generator->next();
    echo PHP_EOL . "Main flow" ;
    $generator->send("aeeewww");
    $generator->next();
    echo $generator->getReturn() .
    PHP_EOL;
    echo PHP_EOL . "Main flow" ;
    $function = function ()
    {
    yield PHP_EOL . "Starting";
    echo PHP_EOL . "-";
    yield PHP_EOL . ".";
    $incoming = yield;
    echo PHP_EOL . $incoming;
    return PHP_EOL .
    "Generator's end.";
    };

    View Slide

  50. $generator = $function();
    echo PHP_EOL . "Main flow" ;
    echo $generator->current();
    echo PHP_EOL . "Main flow" ;
    $generator->next();
    echo $generator->current();
    $generator->next();
    echo PHP_EOL . "Main flow" ;
    $generator->send("aeeewww");
    $generator->next();
    echo $generator->getReturn() .
    PHP_EOL;
    echo PHP_EOL . "Main flow" ;
    $function = function ()
    {
    yield PHP_EOL . "Starting";
    echo PHP_EOL . "-";
    yield PHP_EOL . ".";
    $incoming = yield;
    echo PHP_EOL . $incoming;
    return PHP_EOL .
    "Generator's end.";
    };

    View Slide

  51. $generator = $function();
    echo PHP_EOL . "Main flow" ;
    echo $generator->current();
    echo PHP_EOL . "Main flow" ;
    $generator->next();
    echo $generator->current();
    $generator->next();
    echo PHP_EOL . "Main flow" ;
    $generator->send("aeeewww");
    $generator->next();
    echo $generator->getReturn() .
    PHP_EOL;
    echo PHP_EOL . "Main flow" ;
    $function = function ()
    {
    yield PHP_EOL . "Starting";
    echo PHP_EOL . "-";
    yield PHP_EOL . ".";
    $incoming = yield;
    echo PHP_EOL . $incoming;
    return PHP_EOL .
    "Generator's end.";
    };

    View Slide

  52. $generator = $function();
    echo PHP_EOL . "Main flow" ;
    echo $generator->current();
    echo PHP_EOL . "Main flow" ;
    $generator->next();
    echo $generator->current();
    $generator->next();
    echo PHP_EOL . "Main flow" ;
    $generator->send("aeeewww");
    $generator->next();
    echo $generator->getReturn() .
    PHP_EOL;
    echo PHP_EOL . "Main flow" ;
    $function = function ()
    {
    yield PHP_EOL . "Starting";
    echo PHP_EOL . "-";
    yield PHP_EOL . ".";
    $incoming = yield;
    echo PHP_EOL . $incoming;
    return PHP_EOL .
    "Generator's end.";
    };

    View Slide

  53. $generator = $function();
    echo PHP_EOL . "Main flow" ;
    echo $generator->current();
    echo PHP_EOL . "Main flow" ;
    $generator->next();
    echo $generator->current();
    $generator->next();
    echo PHP_EOL . "Main flow" ;
    $generator->send("aeeewww");
    $generator->next();
    echo $generator->getReturn() .
    PHP_EOL;
    echo PHP_EOL . "Main flow" ;
    $function = function ()
    {
    yield PHP_EOL . "Starting";
    echo PHP_EOL . "-";
    yield PHP_EOL . ".";
    $incoming = yield;
    echo PHP_EOL . $incoming;
    return PHP_EOL .
    "Generator's end.";
    };

    View Slide

  54. $generator = $function();
    echo PHP_EOL . "Main flow" ;
    echo $generator->current();
    echo PHP_EOL . "Main flow" ;
    $generator->next();
    echo $generator->current();
    $generator->next();
    echo PHP_EOL . "Main flow" ;
    $generator->send("aeeewww");
    $generator->next();
    echo $generator->getReturn() .
    PHP_EOL;
    echo PHP_EOL . "Main flow" ;
    $function = function ()
    {
    yield PHP_EOL . "Starting";
    echo PHP_EOL . "-";
    yield PHP_EOL . ".";
    $incoming = yield;
    echo PHP_EOL . $incoming;
    return PHP_EOL .
    "Generator's end.";
    };

    View Slide

  55. $generator = $function();
    echo PHP_EOL . "Main flow" ;
    echo $generator->current();
    echo PHP_EOL . "Main flow" ;
    $generator->next();
    echo $generator->current();
    $generator->next();
    echo PHP_EOL . "Main flow" ;
    $generator->send("aeeewww");
    $generator->next();
    echo $generator->getReturn() .
    PHP_EOL;
    echo PHP_EOL . "Main flow" ;
    $function = function ()
    {
    yield PHP_EOL . "Starting";
    echo PHP_EOL . "-";
    yield PHP_EOL . ".";
    $incoming = yield;
    echo PHP_EOL . $incoming;
    return PHP_EOL .
    "Generator's end.";
    };

    View Slide

  56. $generator = $function();
    echo PHP_EOL . "Main flow" ;
    echo $generator->current();
    echo PHP_EOL . "Main flow" ;
    $generator->next();
    echo $generator->current();
    $generator->next();
    echo PHP_EOL . "Main flow" ;
    $generator->send("aeeewww");
    $generator->next();
    echo $generator->getReturn() .
    PHP_EOL;
    echo PHP_EOL . "Main flow" ;
    $function = function ()
    {
    yield PHP_EOL . "Starting";
    echo PHP_EOL . "-";
    yield PHP_EOL . ".";
    $incoming = yield;
    echo PHP_EOL . $incoming;
    return PHP_EOL .
    "Generator's end.";
    };

    View Slide

  57. $generator = $function();
    echo PHP_EOL . "Main flow" ;
    echo $generator->current();
    echo PHP_EOL . "Main flow" ;
    $generator->next();
    echo $generator->current();
    $generator->next();
    echo PHP_EOL . "Main flow" ;
    $generator->send("aeeewww");
    $generator->next();
    echo $generator->getReturn() .
    PHP_EOL;
    echo PHP_EOL . "Main flow" ;
    $function = function ()
    {
    yield PHP_EOL . "Starting";
    echo PHP_EOL . "-";
    yield PHP_EOL . ".";
    $incoming = yield;
    echo PHP_EOL . $incoming;
    return PHP_EOL .
    "Generator's end.";
    };

    View Slide

  58. $generator = $function();
    echo PHP_EOL . "Main flow" ;
    echo $generator->current();
    echo PHP_EOL . "Main flow" ;
    $generator->next();
    echo $generator->current();
    $generator->next();
    echo PHP_EOL . "Main flow" ;
    $generator->send("aeeewww");
    $generator->next();
    echo $generator->getReturn() .
    PHP_EOL;
    echo PHP_EOL . "Main flow" ;
    $function = function ()
    {
    yield PHP_EOL . "Starting";
    echo PHP_EOL . "-";
    yield PHP_EOL . ".";
    $incoming = yield;
    echo PHP_EOL . $incoming;
    return PHP_EOL .
    "Generator's end.";
    };

    View Slide

  59. $generator = $function();
    echo PHP_EOL . "Main flow" ;
    echo $generator->current();
    echo PHP_EOL . "Main flow" ;
    $generator->next();
    echo $generator->current();
    $generator->next();
    echo PHP_EOL . "Main flow" ;
    $generator->send("aeeewww");
    $generator->next();
    echo $generator->getReturn() .
    PHP_EOL;
    echo PHP_EOL . "Main flow" ;
    $function = function ()
    {
    yield PHP_EOL . "Starting";
    echo PHP_EOL . "-";
    yield PHP_EOL . ".";
    $incoming = yield;
    echo PHP_EOL . $incoming;
    return PHP_EOL .
    "Generator's end.";
    };

    View Slide

  60. $generator = $function();
    echo PHP_EOL . "Main flow" ;
    echo $generator->current();
    echo PHP_EOL . "Main flow" ;
    $generator->next();
    echo $generator->current();
    $generator->next();
    echo PHP_EOL . "Main flow" ;
    $generator->send("aeeewww");
    $generator->next();
    echo $generator->getReturn() .
    PHP_EOL;
    echo PHP_EOL . "Main flow" ;
    $function = function ()
    {
    yield PHP_EOL . "Starting";
    echo PHP_EOL . "-";
    yield PHP_EOL . ".";
    $incoming = yield;
    echo PHP_EOL . $incoming;
    return PHP_EOL .
    "Generator's end.";
    };

    View Slide

  61. $generator = $function();
    echo PHP_EOL . "Main flow" ;
    echo $generator->current();
    echo PHP_EOL . "Main flow" ;
    $generator->next();
    echo $generator->current();
    $generator->next();
    echo PHP_EOL . "Main flow" ;
    $generator->send("aeeewww");
    $generator->next();
    echo $generator->getReturn() .
    PHP_EOL;
    echo PHP_EOL . "Main flow" ;
    $function = function ()
    {
    yield PHP_EOL . "Starting";
    echo PHP_EOL . "-";
    yield PHP_EOL . ".";
    $incoming = yield;
    echo PHP_EOL . $incoming;
    return PHP_EOL .
    "Generator's end.";
    };

    View Slide

  62. Prazer, corrotina.

    View Slide

  63. Mas… e requests?

    View Slide

  64. cURL

    View Slide

  65. cURL

    View Slide

  66. curl_multi_*

    View Slide

  67. $urls = ["http://dummy.restapiexample.com/api/v1/employee/1"
    , "http://dummy.restapiexample.com/api/v1/employee/2"
    ,];
    $multiHandle = curl_multi_init()
    ;
    $curls = [];
    $results = [];
    $callback = function ($data) {
    echo $data . PHP_EOL;
    };
    foreach ($urls as $url) {
    $handle = curl_init()
    ;
    curl_setopt_array(
    $handle, [CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADER => false]);
    $curls[$url] = $handle;
    curl_multi_add_handle(
    $multiHandle
    , $handle);
    }
    $isRunning = null;
    do {
    $multiCurlStatus = curl_multi_exec(
    $multiHandle
    , $isRunning);
    $resource = curl_multi_info_read(
    $multiHandle
    );
    if ($resource) {
    $callback(curl_multi_getcontent(
    $resource['handle']));
    curl_multi_remove_handle(
    $multiHandle
    , $resource['handle']);
    }
    } while ($multiCurlStatus == CURLM_CALL_MULTI_PERFORM || $isRunning);

    View Slide

  68. $urls = ["http://dummy.restapiexample.com/api/v1/employee/1"
    , "http://dummy.restapiexample.com/api/v1/employee/2"
    ,];
    $multiHandle = curl_multi_init()
    ;
    $curls = [];
    $results = [];
    $callback = function ($data) {
    echo $data . PHP_EOL;
    };
    foreach ($urls as $url) {
    $handle = curl_init()
    ;
    curl_setopt_array(
    $handle, [CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADER => false]);
    $curls[$url] = $handle;
    curl_multi_add_handle(
    $multiHandle
    , $handle);
    }
    $isRunning = null;
    do {
    $multiCurlStatus = curl_multi_exec(
    $multiHandle
    , $isRunning);
    $resource = curl_multi_info_read(
    $multiHandle
    );
    if ($resource) {
    $callback(curl_multi_getcontent(
    $resource['handle']));
    curl_multi_remove_handle(
    $multiHandle
    , $resource['handle']);
    }
    } while ($multiCurlStatus == CURLM_CALL_MULTI_PERFORM || $isRunning);

    View Slide

  69. $urls = ["http://dummy.restapiexample.com/api/v1/employee/1"
    , "http://dummy.restapiexample.com/api/v1/employee/2"
    ,];
    $multiHandle = curl_multi_init()
    ;
    $curls = [];
    $results = [];
    $callback = function ($data) {
    echo $data . PHP_EOL;
    };
    foreach ($urls as $url) {
    $handle = curl_init()
    ;
    curl_setopt_array(
    $handle, [CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADER => false]);
    $curls[$url] = $handle;
    curl_multi_add_handle(
    $multiHandle
    , $handle);
    }
    $isRunning = null;
    do {
    $multiCurlStatus = curl_multi_exec(
    $multiHandle
    , $isRunning);
    $resource = curl_multi_info_read(
    $multiHandle
    );
    if ($resource) {
    $callback(curl_multi_getcontent(
    $resource['handle']));
    curl_multi_remove_handle(
    $multiHandle
    , $resource['handle']);
    }
    } while ($multiCurlStatus == CURLM_CALL_MULTI_PERFORM || $isRunning);

    View Slide

  70. $urls = ["http://dummy.restapiexample.com/api/v1/employee/1"
    , "http://dummy.restapiexample.com/api/v1/employee/2"
    ,];
    $multiHandle = curl_multi_init()
    ;
    $curls = [];
    $results = [];
    $callback = function ($data) {
    echo $data . PHP_EOL;
    };
    foreach ($urls as $url) {
    $handle = curl_init()
    ;
    curl_setopt_array(
    $handle, [CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADER => false]);
    $curls[$url] = $handle;
    curl_multi_add_handle(
    $multiHandle
    , $handle);
    }
    $isRunning = null;
    do {
    $multiCurlStatus = curl_multi_exec(
    $multiHandle
    , $isRunning);
    $resource = curl_multi_info_read(
    $multiHandle
    );
    if ($resource) {
    $callback(curl_multi_getcontent(
    $resource['handle']));
    curl_multi_remove_handle(
    $multiHandle
    , $resource['handle']);
    }
    } while ($multiCurlStatus == CURLM_CALL_MULTI_PERFORM || $isRunning);

    View Slide

  71. $urls = ["http://dummy.restapiexample.com/api/v1/employee/1"
    , "http://dummy.restapiexample.com/api/v1/employee/2"
    ,];
    $multiHandle = curl_multi_init()
    ;
    $curls = [];
    $results = [];
    $callback = function ($data) {
    echo $data . PHP_EOL;
    };
    foreach ($urls as $url) {
    $handle = curl_init()
    ;
    curl_setopt_array(
    $handle, [CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADER => false]);
    $curls[$url] = $handle;
    curl_multi_add_handle(
    $multiHandle
    , $handle);
    }
    $isRunning = null;
    do {
    $multiCurlStatus = curl_multi_exec(
    $multiHandle
    , $isRunning);
    $resource = curl_multi_info_read(
    $multiHandle
    );
    if ($resource) {
    $callback(curl_multi_getcontent(
    $resource['handle']));
    curl_multi_remove_handle(
    $multiHandle
    , $resource['handle']);
    }
    } while ($multiCurlStatus == CURLM_CALL_MULTI_PERFORM || $isRunning);

    View Slide

  72. $urls = ["http://dummy.restapiexample.com/api/v1/employee/1"
    , "http://dummy.restapiexample.com/api/v1/employee/2"
    ,];
    $multiHandle = curl_multi_init()
    ;
    $curls = [];
    $results = [];
    $callback = function ($data) {
    echo $data . PHP_EOL;
    };
    foreach ($urls as $url) {
    $handle = curl_init()
    ;
    curl_setopt_array(
    $handle, [CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADER => false]);
    $curls[$url] = $handle;
    curl_multi_add_handle(
    $multiHandle
    , $handle);
    }
    $isRunning = null;
    do {
    $multiCurlStatus = curl_multi_exec(
    $multiHandle
    , $isRunning);
    $resource = curl_multi_info_read(
    $multiHandle
    );
    if ($resource) {
    $callback(curl_multi_getcontent(
    $resource['handle']));
    curl_multi_remove_handle(
    $multiHandle
    , $resource['handle']);
    }
    } while ($multiCurlStatus == CURLM_CALL_MULTI_PERFORM || $isRunning);

    View Slide

  73. $urls = ["http://dummy.restapiexample.com/api/v1/employee/1"
    , "http://dummy.restapiexample.com/api/v1/employee/2"
    ,];
    $multiHandle = curl_multi_init()
    ;
    $curls = [];
    $results = [];
    $callback = function ($data) {
    echo $data . PHP_EOL;
    };
    foreach ($urls as $url) {
    $handle = curl_init()
    ;
    curl_setopt_array(
    $handle, [CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADER => false]);
    $curls[$url] = $handle;
    curl_multi_add_handle(
    $multiHandle
    , $handle);
    }
    $isRunning = null;
    do {
    $multiCurlStatus = curl_multi_exec(
    $multiHandle
    , $isRunning);
    $resource = curl_multi_info_read(
    $multiHandle
    );
    if ($resource) {
    $callback(curl_multi_getcontent(
    $resource['handle']));
    curl_multi_remove_handle(
    $multiHandle
    , $resource['handle']);
    }
    } while ($multiCurlStatus == CURLM_CALL_MULTI_PERFORM || $isRunning);

    View Slide

  74. $urls = ["http://dummy.restapiexample.com/api/v1/employee/1"
    , "http://dummy.restapiexample.com/api/v1/employee/2"
    ,];
    $multiHandle = curl_multi_init()
    ;
    $curls = [];
    $results = [];
    $callback = function ($data) {
    echo $data . PHP_EOL;
    };
    foreach ($urls as $url) {
    $handle = curl_init()
    ;
    curl_setopt_array(
    $handle, [CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADER => false]);
    $curls[$url] = $handle;
    curl_multi_add_handle(
    $multiHandle
    , $handle);
    }
    $isRunning = null;
    do {
    $multiCurlStatus = curl_multi_exec(
    $multiHandle
    , $isRunning);
    $resource = curl_multi_info_read(
    $multiHandle
    );
    if ($resource) {
    $callback(curl_multi_getcontent(
    $resource['handle']));
    curl_multi_remove_handle(
    $multiHandle
    , $resource['handle']);
    }
    } while ($multiCurlStatus == CURLM_CALL_MULTI_PERFORM || $isRunning);

    View Slide

  75. $urls = ["http://dummy.restapiexample.com/api/v1/employee/1"
    , "http://dummy.restapiexample.com/api/v1/employee/2"
    ,];
    $multiHandle = curl_multi_init()
    ;
    $curls = [];
    $results = [];
    $callback = function ($data) {
    echo $data . PHP_EOL;
    };
    foreach ($urls as $url) {
    $handle = curl_init()
    ;
    curl_setopt_array(
    $handle, [CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADER => false]);
    $curls[$url] = $handle;
    curl_multi_add_handle(
    $multiHandle
    , $handle);
    }
    $isRunning = null;
    do {
    $multiCurlStatus = curl_multi_exec(
    $multiHandle
    , $isRunning);
    $resource = curl_multi_info_read(
    $multiHandle
    );
    if ($resource) {
    $callback(curl_multi_getcontent(
    $resource['handle']));
    curl_multi_remove_handle(
    $multiHandle
    , $resource['handle']);
    }
    } while ($multiCurlStatus == CURLM_CALL_MULTI_PERFORM || $isRunning);

    View Slide

  76. $urls = ["http://dummy.restapiexample.com/api/v1/employee/1"
    , "http://dummy.restapiexample.com/api/v1/employee/2"
    ,];
    $multiHandle = curl_multi_init()
    ;
    $curls = [];
    $results = [];
    $callback = function ($data) {
    echo $data . PHP_EOL;
    };
    foreach ($urls as $url) {
    $handle = curl_init()
    ;
    curl_setopt_array(
    $handle, [CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADER => false]);
    $curls[$url] = $handle;
    curl_multi_add_handle(
    $multiHandle
    , $handle);
    }
    $isRunning = null;
    do {
    $multiCurlStatus = curl_multi_exec(
    $multiHandle
    , $isRunning);
    $resource = curl_multi_info_read(
    $multiHandle
    );
    if ($resource) {
    $callback(curl_multi_getcontent(
    $resource['handle']));
    curl_multi_remove_handle(
    $multiHandle
    , $resource['handle']);
    }
    } while ($multiCurlStatus == CURLM_CALL_MULTI_PERFORM || $isRunning);

    View Slide

  77. $urls = ["http://dummy.restapiexample.com/api/v1/employee/1"
    , "http://dummy.restapiexample.com/api/v1/employee/2"
    ,];
    $multiHandle = curl_multi_init()
    ;
    $curls = [];
    $results = [];
    $callback = function ($data) {
    echo $data . PHP_EOL;
    };
    foreach ($urls as $url) {
    $handle = curl_init()
    ;
    curl_setopt_array(
    $handle, [CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADER => false]);
    $curls[$url] = $handle;
    curl_multi_add_handle(
    $multiHandle
    , $handle);
    }
    $isRunning = null;
    do {
    $multiCurlStatus = curl_multi_exec(
    $multiHandle
    , $isRunning);
    $resource = curl_multi_info_read(
    $multiHandle
    );
    if ($resource) {
    $callback(curl_multi_getcontent(
    $resource['handle']));
    curl_multi_remove_handle(
    $multiHandle
    , $resource['handle']);
    }
    } while ($multiCurlStatus == CURLM_CALL_MULTI_PERFORM || $isRunning);

    View Slide

  78. $urls = ["http://dummy.restapiexample.com/api/v1/employee/1"
    , "http://dummy.restapiexample.com/api/v1/employee/2"
    ,];
    $multiHandle = curl_multi_init()
    ;
    $curls = [];
    $results = [];
    $callback = function ($data) {
    echo $data . PHP_EOL;
    };
    foreach ($urls as $url) {
    $handle = curl_init()
    ;
    curl_setopt_array(
    $handle, [CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADER => false]);
    $curls[$url] = $handle;
    curl_multi_add_handle(
    $multiHandle
    , $handle);
    }
    $isRunning = null;
    do {
    $multiCurlStatus = curl_multi_exec(
    $multiHandle
    , $isRunning);
    $resource = curl_multi_info_read(
    $multiHandle
    );
    if ($resource) {
    $callback(curl_multi_getcontent(
    $resource['handle']));
    curl_multi_remove_handle(
    $multiHandle
    , $resource['handle']);
    }
    } while ($multiCurlStatus == CURLM_CALL_MULTI_PERFORM || $isRunning);

    View Slide

  79. $urls = ["http://dummy.restapiexample.com/api/v1/employee/1"
    , "http://dummy.restapiexample.com/api/v1/employee/2"
    ,];
    $multiHandle = curl_multi_init()
    ;
    $curls = [];
    $results = [];
    $callback = function ($data) {
    echo $data . PHP_EOL;
    };
    foreach ($urls as $url) {
    $handle = curl_init()
    ;
    curl_setopt_array(
    $handle, [CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADER => false]);
    $curls[$url] = $handle;
    curl_multi_add_handle(
    $multiHandle
    , $handle);
    }
    $isRunning = null;
    do {
    $multiCurlStatus = curl_multi_exec(
    $multiHandle
    , $isRunning);
    $resource = curl_multi_info_read(
    $multiHandle
    );
    if ($resource) {
    $callback(curl_multi_getcontent(
    $resource['handle']));
    curl_multi_remove_handle(
    $multiHandle
    , $resource['handle']);
    }
    } while ($multiCurlStatus == CURLM_CALL_MULTI_PERFORM || $isRunning);

    View Slide

  80. View Slide

  81. Concorrência assíncrona :)

    View Slide

  82. Mas tem mais!

    View Slide

  83. I/O multiplexing com… stream_select

    View Slide

  84. $host = "dummy.restapiexample.com";
    $resource = [
    "api/v1/employee/1",
    "api/v1/employee/2",
    ];
    $clients = [];
    foreach ($resource as $url) {
    $socketClient = stream_socket_client(
    'tcp://' . $host . ':80',
    $errno,
    $errstr,
    10,
    STREAM_CLIENT_ASYNC_CONNECT
    );
    $clients[$url] = $socketClient;
    $request = "GET /" . $url . " HTTP/1.1" . PHP_EOL . "Host: " . $host . PHP_EOL . PHP_EOL;
    fwrite($socketClient, $request);
    stream_set_blocking($socketClient, 0);
    }
    stream_select($clients, $write, $ex, 10);
    if (count($clients)) {
    foreach ($clients as $id => $socket) {
    echo fread($socket, 2000);
    }
    }

    View Slide

  85. $host = "dummy.restapiexample.com";
    $resource = [
    "api/v1/employee/1",
    "api/v1/employee/2",
    ];
    $clients = [];
    foreach ($resource as $url) {
    $socketClient = stream_socket_client(
    'tcp://' . $host . ':80',
    $errno,
    $errstr,
    10,
    STREAM_CLIENT_ASYNC_CONNECT
    );
    $clients[$url] = $socketClient;
    $request = "GET /" . $url . " HTTP/1.1" . PHP_EOL . "Host: " . $host . PHP_EOL . PHP_EOL;
    fwrite($socketClient, $request);
    stream_set_blocking($socketClient, 0);
    }
    stream_select($clients, $write, $ex, 10);
    if (count($clients)) {
    foreach ($clients as $id => $socket) {
    echo fread($socket, 2000);
    }
    }

    View Slide

  86. $host = "dummy.restapiexample.com";
    $resource = [
    "api/v1/employee/1",
    "api/v1/employee/2",
    ];
    $clients = [];
    foreach ($resource as $url) {
    $socketClient = stream_socket_client(
    'tcp://' . $host . ':80',
    $errno,
    $errstr,
    10,
    STREAM_CLIENT_ASYNC_CONNECT
    );
    $clients[$url] = $socketClient;
    $request = "GET /" . $url . " HTTP/1.1" . PHP_EOL . "Host: " . $host . PHP_EOL . PHP_EOL;
    fwrite($socketClient, $request);
    stream_set_blocking($socketClient, 0);
    }
    stream_select($clients, $write, $ex, 10);
    if (count($clients)) {
    foreach ($clients as $id => $socket) {
    echo fread($socket, 2000);
    }
    }

    View Slide

  87. $host = "dummy.restapiexample.com";
    $resource = [
    "api/v1/employee/1",
    "api/v1/employee/2",
    ];
    $clients = [];
    foreach ($resource as $url) {
    $socketClient = stream_socket_client(
    'tcp://' . $host . ':80',
    $errno,
    $errstr,
    10,
    STREAM_CLIENT_ASYNC_CONNECT
    );
    $clients[$url] = $socketClient;
    $request = "GET /" . $url . " HTTP/1.1" . PHP_EOL . "Host: " . $host . PHP_EOL . PHP_EOL;
    fwrite($socketClient, $request);
    stream_set_blocking($socketClient, 0);
    }
    stream_select($clients, $write, $ex, 10);
    if (count($clients)) {
    foreach ($clients as $id => $socket) {
    echo fread($socket, 2000);
    }
    }

    View Slide

  88. $host = "dummy.restapiexample.com";
    $resource = [
    "api/v1/employee/1",
    "api/v1/employee/2",
    ];
    $clients = [];
    foreach ($resource as $url) {
    $socketClient = stream_socket_client(
    'tcp://' . $host . ':80',
    $errno,
    $errstr,
    10,
    STREAM_CLIENT_ASYNC_CONNECT
    );
    $clients[$url] = $socketClient;
    $request = "GET /" . $url . " HTTP/1.1" . PHP_EOL . "Host: " . $host . PHP_EOL . PHP_EOL;
    fwrite($socketClient, $request);
    stream_set_blocking($socketClient, 0);
    }
    stream_select($clients, $write, $ex, 10);
    if (count($clients)) {
    foreach ($clients as $id => $socket) {
    echo fread($socket, 2000);
    }
    }

    View Slide

  89. $host = "dummy.restapiexample.com";
    $resource = [
    "api/v1/employee/1",
    "api/v1/employee/2",
    ];
    $clients = [];
    foreach ($resource as $url) {
    $socketClient = stream_socket_client(
    'tcp://' . $host . ':80',
    $errno,
    $errstr,
    10,
    STREAM_CLIENT_ASYNC_CONNECT
    );
    $clients[$url] = $socketClient;
    $request = "GET /" . $url . " HTTP/1.1" . PHP_EOL . "Host: " . $host . PHP_EOL . PHP_EOL;
    fwrite($socketClient, $request);
    stream_set_blocking($socketClient, 0);
    }
    stream_select($clients, $write, $ex, 10);
    if (count($clients)) {
    foreach ($clients as $id => $socket) {
    echo fread($socket, 2000);
    }
    }

    View Slide

  90. $host = "dummy.restapiexample.com";
    $resource = [
    "api/v1/employee/1",
    "api/v1/employee/2",
    ];
    $clients = [];
    foreach ($resource as $url) {
    $socketClient = stream_socket_client(
    'tcp://' . $host . ':80',
    $errno,
    $errstr,
    10,
    STREAM_CLIENT_ASYNC_CONNECT
    );
    $clients[$url] = $socketClient;
    $request = "GET /" . $url . " HTTP/1.1" . PHP_EOL . "Host: " . $host . PHP_EOL . PHP_EOL;
    fwrite($socketClient, $request);
    stream_set_blocking($socketClient, 0);
    }
    stream_select($clients, $write, $ex, 10);
    if (count($clients)) {
    foreach ($clients as $id => $socket) {
    echo fread($socket, 2000);
    }
    }

    View Slide

  91. $host = "dummy.restapiexample.com";
    $resource = [
    "api/v1/employee/1",
    "api/v1/employee/2",
    ];
    $clients = [];
    foreach ($resource as $url) {
    $socketClient = stream_socket_client(
    'tcp://' . $host . ':80',
    $errno,
    $errstr,
    10,
    STREAM_CLIENT_ASYNC_CONNECT
    );
    $clients[$url] = $socketClient;
    $request = "GET /" . $url . " HTTP/1.1" . PHP_EOL . "Host: " . $host . PHP_EOL . PHP_EOL;
    fwrite($socketClient, $request);
    stream_set_blocking($socketClient, 0);
    }
    stream_select($clients, $write, $ex, 10);
    if (count($clients)) {
    foreach ($clients as $id => $socket) {
    echo fread($socket, 2000);
    }
    }

    View Slide

  92. MAIS AINDA!

    View Slide

  93. MAIS AINDA!
    Eventos com stream context

    View Slide

  94. public function download
    ()
    {
    $context = stream_context_create()
    ;
    stream_context_set_params(
    $context
    , ['notification' => [Downloader::
    class, 'streamCallback'
    ]]);
    $handler = fopen(
    $this->youtube->getUrl(), 'r', false, $context
    );
    if (!$handler
    ) {
    throw new \InvalidArgumentException(
    "Unable to download from link "
    . $this->youtube->getUrl());
    }
    file_put_contents(
    $this->youtube->getName(), $handler
    );
    }
    public function streamCallback
    ($notification_code
    , $severity
    , $message
    , $message_code
    , $bytes_transfered
    , $bytes_max
    )
    {
    static $filesize = null;
    switch ($notification_code
    ) {
    case STREAM_NOTIFY_RESOLVE:
    case STREAM_NOTIFY_AUTH_REQUIRED:
    case STREAM_NOTIFY_COMPLETED:
    case STREAM_NOTIFY_FAILURE:
    case STREAM_NOTIFY_AUTH_RESULT:
    break;
    case STREAM_NOTIFY_REDIRECTED:
    echo "Being redirected to: " . $message . PHP_EOL;
    break;
    case STREAM_NOTIFY_CONNECT:
    echo "Connected!" . PHP_EOL;
    case STREAM_NOTIFY_FILE_SIZE_IS:
    $filesize = $bytes_max
    ;
    echo "Filesize: " . $filesize . PHP_EOL;
    case STREAM_NOTIFY_MIME_TYPE_IS:
    echo "Mime-type: " . $message . PHP_EOL;
    case STREAM_NOTIFY_PROGRESS:
    if ($bytes_transfered > 0) {
    $length = (int)(($bytes_transfered / $filesize
    ) * 100);
    printf("\r[%-100s] %d%% (%2d/%2d mb)"
    , str_repeat(
    "=", $length) . ">", $length, ($bytes_transfered / 1024 / 1024), $filesize / 1024 / 1024);
    }
    break;
    }
    }

    View Slide

  95. public function download
    ()
    {
    $context = stream_context_create()
    ;
    stream_context_set_params(
    $context
    , ['notification' => [Downloader::
    class, 'streamCallback'
    ]]);
    $handler = fopen(
    $this->youtube->getUrl(), 'r', false, $context
    );
    if (!$handler
    ) {
    throw new \InvalidArgumentException(
    "Unable to download from link "
    . $this->youtube->getUrl());
    }
    file_put_contents(
    $this->youtube->getName(), $handler
    );
    }
    public function streamCallback
    ($notification_code
    , $severity
    , $message
    , $message_code
    , $bytes_transfered
    , $bytes_max
    )
    {
    static $filesize = null;
    switch ($notification_code
    ) {
    case STREAM_NOTIFY_RESOLVE:
    case STREAM_NOTIFY_AUTH_REQUIRED:
    case STREAM_NOTIFY_COMPLETED:
    case STREAM_NOTIFY_FAILURE:
    case STREAM_NOTIFY_AUTH_RESULT:
    break;
    case STREAM_NOTIFY_REDIRECTED:
    echo "Being redirected to: " . $message . PHP_EOL;
    break;
    case STREAM_NOTIFY_CONNECT:
    echo "Connected!" . PHP_EOL;
    case STREAM_NOTIFY_FILE_SIZE_IS:
    $filesize = $bytes_max
    ;
    echo "Filesize: " . $filesize . PHP_EOL;
    case STREAM_NOTIFY_MIME_TYPE_IS:
    echo "Mime-type: " . $message . PHP_EOL;
    case STREAM_NOTIFY_PROGRESS:
    if ($bytes_transfered > 0) {
    $length = (int)(($bytes_transfered / $filesize
    ) * 100);
    printf("\r[%-100s] %d%% (%2d/%2d mb)"
    , str_repeat(
    "=", $length) . ">", $length, ($bytes_transfered / 1024 / 1024), $filesize / 1024 / 1024);
    }
    break;
    }
    }

    View Slide

  96. public function download
    ()
    {
    $context = stream_context_create()
    ;
    stream_context_set_params(
    $context
    , ['notification' => [Downloader::
    class, 'streamCallback'
    ]]);
    $handler = fopen(
    $this->youtube->getUrl(), 'r', false, $context
    );
    if (!$handler
    ) {
    throw new \InvalidArgumentException(
    "Unable to download from link "
    . $this->youtube->getUrl());
    }
    file_put_contents(
    $this->youtube->getName(), $handler
    );
    }
    public function streamCallback
    ($notification_code
    , $severity
    , $message
    , $message_code
    , $bytes_transfered
    , $bytes_max
    )
    {
    static $filesize = null;
    switch ($notification_code
    ) {
    case STREAM_NOTIFY_RESOLVE:
    case STREAM_NOTIFY_AUTH_REQUIRED:
    case STREAM_NOTIFY_COMPLETED:
    case STREAM_NOTIFY_FAILURE:
    case STREAM_NOTIFY_AUTH_RESULT:
    break;
    case STREAM_NOTIFY_REDIRECTED:
    echo "Being redirected to: " . $message . PHP_EOL;
    break;
    case STREAM_NOTIFY_CONNECT:
    echo "Connected!" . PHP_EOL;
    case STREAM_NOTIFY_FILE_SIZE_IS:
    $filesize = $bytes_max
    ;
    echo "Filesize: " . $filesize . PHP_EOL;
    case STREAM_NOTIFY_MIME_TYPE_IS:
    echo "Mime-type: " . $message . PHP_EOL;
    case STREAM_NOTIFY_PROGRESS:
    if ($bytes_transfered > 0) {
    $length = (int)(($bytes_transfered / $filesize
    ) * 100);
    printf("\r[%-100s] %d%% (%2d/%2d mb)"
    , str_repeat(
    "=", $length) . ">", $length, ($bytes_transfered / 1024 / 1024), $filesize / 1024 / 1024);
    }
    break;
    }
    }

    View Slide

  97. public function download
    ()
    {
    $context = stream_context_create()
    ;
    stream_context_set_params(
    $context
    , ['notification' => [Downloader::
    class, 'streamCallback'
    ]]);
    $handler = fopen(
    $this->youtube->getUrl(), 'r', false, $context
    );
    if (!$handler
    ) {
    throw new \InvalidArgumentException(
    "Unable to download from link "
    . $this->youtube->getUrl());
    }
    file_put_contents(
    $this->youtube->getName(), $handler
    );
    }
    public function streamCallback
    ($notification_code
    , $severity
    , $message
    , $message_code
    , $bytes_transfered
    , $bytes_max
    )
    {
    static $filesize = null;
    switch ($notification_code
    ) {
    case STREAM_NOTIFY_RESOLVE:
    case STREAM_NOTIFY_AUTH_REQUIRED:
    case STREAM_NOTIFY_COMPLETED:
    case STREAM_NOTIFY_FAILURE:
    case STREAM_NOTIFY_AUTH_RESULT:
    break;
    case STREAM_NOTIFY_REDIRECTED:
    echo "Being redirected to: " . $message . PHP_EOL;
    break;
    case STREAM_NOTIFY_CONNECT:
    echo "Connected!" . PHP_EOL;
    case STREAM_NOTIFY_FILE_SIZE_IS:
    $filesize = $bytes_max
    ;
    echo "Filesize: " . $filesize . PHP_EOL;
    case STREAM_NOTIFY_MIME_TYPE_IS:
    echo "Mime-type: " . $message . PHP_EOL;
    case STREAM_NOTIFY_PROGRESS:
    if ($bytes_transfered > 0) {
    $length = (int)(($bytes_transfered / $filesize
    ) * 100);
    printf("\r[%-100s] %d%% (%2d/%2d mb)"
    , str_repeat(
    "=", $length) . ">", $length, ($bytes_transfered / 1024 / 1024), $filesize / 1024 / 1024);
    }
    break;
    }
    }

    View Slide

  98. public function download
    ()
    {
    $context = stream_context_create()
    ;
    stream_context_set_params(
    $context
    , ['notification' => [Downloader::
    class, 'streamCallback'
    ]]);
    $handler = fopen(
    $this->youtube->getUrl(), 'r', false, $context
    );
    if (!$handler
    ) {
    throw new \InvalidArgumentException(
    "Unable to download from link "
    . $this->youtube->getUrl());
    }
    file_put_contents(
    $this->youtube->getName(), $handler
    );
    }
    public function streamCallback
    ($notification_code
    , $severity
    , $message
    , $message_code
    , $bytes_transfered
    , $bytes_max
    )
    {
    static $filesize = null;
    switch ($notification_code
    ) {
    case STREAM_NOTIFY_RESOLVE:
    case STREAM_NOTIFY_AUTH_REQUIRED:
    case STREAM_NOTIFY_COMPLETED:
    case STREAM_NOTIFY_FAILURE:
    case STREAM_NOTIFY_AUTH_RESULT:
    break;
    case STREAM_NOTIFY_REDIRECTED:
    echo "Being redirected to: " . $message . PHP_EOL;
    break;
    case STREAM_NOTIFY_CONNECT:
    echo "Connected!" . PHP_EOL;
    case STREAM_NOTIFY_FILE_SIZE_IS:
    $filesize = $bytes_max
    ;
    echo "Filesize: " . $filesize . PHP_EOL;
    case STREAM_NOTIFY_MIME_TYPE_IS:
    echo "Mime-type: " . $message . PHP_EOL;
    case STREAM_NOTIFY_PROGRESS:
    if ($bytes_transfered > 0) {
    $length = (int)(($bytes_transfered / $filesize
    ) * 100);
    printf("\r[%-100s] %d%% (%2d/%2d mb)"
    , str_repeat(
    "=", $length) . ">", $length, ($bytes_transfered / 1024 / 1024), $filesize / 1024 / 1024);
    }
    break;
    }
    }

    View Slide

  99. Forks?
    pnct_*

    View Slide

  100. $pid = pcntl_fork() ;
    if ($pid == -1) {
    die('could not fork' );
    } else if ($pid) {
    // we are the parent
    pcntl_wait($status); //Protect against Zombie children
    } else {
    // we are the child
    }

    View Slide

  101. Só funciona em Linux

    View Slide

  102. Só funciona em Linux
    Limitado ao número de CPUs

    View Slide

  103. Fork != Thread

    View Slide

  104. - Concorrência paralela

    View Slide

  105. - Concorrência paralela
    - Concorrência assíncrona

    View Slide

  106. - Concorrência paralela
    - Concorrência assíncrona
    - Eventos

    View Slide

  107. - Concorrência paralela
    - Concorrência assíncrona
    - Eventos
    - Paralelização

    View Slide

  108. View Slide

  109. Você tem seu próprio ReactPHP, Amp,
    etc...

    View Slide

  110. Ahhhh, mas se fosse Java...

    View Slide

  111. O PHP também faz.

    View Slide

  112. REFERÊNCIAS
    http://bit.ly/pcs2020-ref

    View Slide

  113. SLIDES
    http://bit.ly/pcs2020-slides

    View Slide

  114. JOIND.IN
    https://joind.in/talk/43ab3

    View Slide

  115. OBRIGADA!
    Fale comigo: @dianaarnos

    View Slide