I have the following two functions
public function myEndpoint(){
$this->logger->debug('Started');
$this->guzzle->requestAsync('post', 'http://myurl.com/doNotWait')->wait();
$this->logger->debug("I shouldn't wait");
}
public function doNotWait(){
sleep(10);
$this->logger->debug("You shouldn't wait");
}
Now what I need to see in my logs is:
I shouldn't wait
You shouldn't wait
But what I see
You shouldn't wait
I shouldn't wait
Also I tried using the following ways:
Way 1
public function myEndpoint(){
$this->logger->debug('Started');
$this->guzzle->requestAsync('post', 'http://myurl.com/doNotWait', ['synchronous' => false])->wait();
$this->logger->debug("I shouldn't wait");
}
Way 2
public function myEndpoint(){
$this->logger->debug('Started');
$this->guzzle->requestAsync('post', 'http://myurl.com/doNotWait');
$queue = \GuzzleHttp\Promise\queue()->run();
$this->logger->debug("I shouldn't wait");
}
But the result is never the desired one. Is there a way to do this? I am using Guzzle 6.x.
I also found out this. http://stackoverflow.com/a/2190973/4158811
I really can't understand if this is valid. If it is why there are functions in guzzle with the suffix Async?
What is the real difference between postAsync and post then?
Reference https://github.com/guzzle/guzzle/blob/master/src/Client.php#L126 , calling $client->requestAsync()->wait() === $client->request() The code sample provided, is operating synchronously.
The async methods are abstractions for Client::requestAsync(), which returns a promise. Reference https://github.com/guzzle/promises#synchronous-wait, calling Promise::wait() "is used to synchronously force a promise to complete".
You would have to do some pretty deep, custom handler code in order to "fire and forget" with Guzzle. Guzzle is designed to send complete requests, allowing us to know if the request actually succeeded.
You could try calling the *async() functions of the client to send requests and never call wait() on them. This would allow you to fire off a bunch of requests in your script, and when it shuts down, all of the pending requests will be waited upon.
If you want true async, then you'll need to spin up a thread using something like pthreads, send requests off to a thread pool, hook up a custom handler and promise to work with this. It sounds pretty complicated and would take someone probably contributing a significant amount of refactoring code to Guzzle and guzzle/promises.
You could also try going event-loop async by using the Guzzle react handler: https://github.com/WyriHaximus/react-guzzle-psr7
@mtdowling I hope you don't mind me asking, but what about changing the CurlMultiHandler::tick method to do something a bit different than:
while ($x = curl_multi_exec($this->_mh, $this->active) === CURLM_CALL_MULTI_PERFORM);
One option that came into my mind, which is of course a very basic prototype, is to replace it with:
do {
curl_multi_exec($this->_mh, $this->active);
// added a usleep for 0.25 seconds to reduce load
usleep(250000);
} while ($this->active > 0);
That way, all current available waiting calls, either it's only 1 call or many, are triggered directly and the client can decide if they want to have a callback or just forget about the response.
I made a very basic example: https://gist.github.com/Shaked/bf260a1defc517c3fd92000bf1cc25b6.
What do you think? Would it make sense?
Thank you for your time and help!
Shaked
@mtdowling I've used guzzle to post "fire & forget" by setting the response timeout to as low as possible.
I left the connection timeout as the default so requests are sent, received on the other end, the transfer is acknowledged and only then the response timeout starts being counted.
Most helpful comment
@mtdowling I've used guzzle to post "fire & forget" by setting the response timeout to as low as possible.
I left the connection timeout as the default so requests are sent, received on the other end, the transfer is acknowledged and only then the response timeout starts being counted.