Times consultation with Guzzle supposedly parallel mind does not work

0

I am trying to consult several different webservices in parallel with Guzzle (in laravel ), but when I take time, I understand that it is being done sequentially, one by one, instead of all together and at the same time. The individual query to a single webservice, the one that takes the most, takes 4 seconds, which I understand that being parallel, should be the maximum time. Instead, by doing 3 request , I get a delay of 12 seconds when consulting 3 webservices . I'm using Guzzle with promises, but I do not know if it's the right way.

This is my code:

$client = new Client();

$promises['resultado1']= $client->postAsync('http://undominio.com',['headers' => $headers,'body' => $body]);

$promises['resultado2']= $client->postAsync('http://otrodominiodiferentealprimero',['headers' => $headers,'body' => $body]);

$promises['resultado3']= $client->postAsync('http://untercerdominiodiferenteatodos',['headers' => $headers,'body' => $body]);

$results = Promise\settle($promises)->wait();
    
asked by rendor9 27.11.2017 в 15:52
source

1 answer

1

It is assumed that when initializing $client with new GuzzleHttp\Client() if you do not pass a handler explicit%, the client instance chooses the best handler for you.

When you do not have curl or php-curl installed, the default handler is StreamHandler .

Think of an endpoint endpoint.php that receives a parameter as a parameter and responds after that time

<?php
//endpoint.php    
sleep($_GET['wait']);
echo 'listo';

According to the Handlers documentation , if you explicitly used the StreamHandler

$handler = new \GuzzleHttp\Handler\StreamHandler();
$stack   = \GuzzleHttp\HandlerStack::create($handler); 
$client  = new \GuzzleHttp\Client(['handler' => $stack]);

$tini                = time();
$promises            = [];
$promises['demora3'] = $client->getAsync('http://sitio.com/endpoint.php?wait=3');
$promises['demora2'] = $client->getAsync('http://sitio.com/endpoint.php?wait=2');
$promises['demora1'] = $client->getAsync('http://sitio.com/endpoint.php?wait=1');

$promises['demora3']->then(function ($res) use ($tini) {
    echo '<br> demora3: demoró ' . (time() - $tini) . ' segundos ';
});
$promises['demora2']->then(function ($res) use ($tini) {
    echo '<br> demora2: demoró ' . (time() - $tini) . ' segundos ';
});
$promises['demora1']->then(function ($res) use ($tini) {
    echo '<br> demora1: demoró ' . (time() - $tini) . ' segundos ';
});

$results = \GuzzleHttp\Promise\settle($promises)->wait();

Requests would be solved in a synchronous way and the result would be:

demora3: demoró 6 segundos 
demora2: demoró 6 segundos 
demora1: demoró 6 segundos

Because it took 1 + 2 + 3 seconds in total.

To achieve what you want, you would have to have curl installed on your system, and the php-curl extension, and for more security, explicitly tell you that you want to use CurlMultiHandler .

$handler = new \GuzzleHttp\Handler\CurlMultiHandler();
$stack   = \GuzzleHttp\HandlerStack::create($handler); 
$client  = new \GuzzleHttp\Client(['handler' => $stack]);

$tini                = time();
$promises            = [];
$promises['demora3'] = $client->getAsync('http://sitio.com/endpoint.php?wait=3');
$promises['demora2'] = $client->getAsync('http://sitio.com/endpoint.php?wait=2');
$promises['demora1'] = $client->getAsync('http://sitio.com/endpoint.php?wait=1');

$promises['demora3']->then(function ($res) use ($tini) {
    echo '<br> demora3: demoró ' . (time() - $tini) . ' segundos ';
});
$promises['demora2']->then(function ($res) use ($tini) {
    echo '<br> demora2: demoró ' . (time() - $tini) . ' segundos ';
});
$promises['demora1']->then(function ($res) use ($tini) {
    echo '<br> demora1: demoró ' . (time() - $tini) . ' segundos ';
});

$results = \GuzzleHttp\Promise\settle($promises)->wait();

And you should get:

demora1: demoró 1 segundos 
demora2: demoró 2 segundos 
demora3: demoró 3 segundos
    
answered by 27.11.2017 в 19:14