Reputation: 2277
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:
Started
I shouldn't wait
You shouldn't wait
But what I see
Started
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. Any idea? I am using Guzzle 6.x.
Upvotes: 25
Views: 29092
Reputation: 3309
Since others wrote, that Guzzle doesn't offer a build in solution for this, here is a solution as one liner:
$url = escapeshellarg("http://myurl.com/doNotWait");
exec("wget -O /dev/null -o /dev/null " . $url . " --background")
It uses exec (https://www.php.net/manual/de/function.exec.php) to run the commandline tool wget
(https://de.wikipedia.org/wiki/Wget - its included in most linux distries and also works in Windows and OSX) command. I have tested it only on linux, so maybe the params have to be adjusted for your OS.
Lets split it up into parts
-O /dev/null
: The result of the request should be send to null (nowhere)-o /dev/null
: The logs should be send to null$url
: The url you wanna call, for example http://myurl.com/doNotWait
--background
: Run in background, do not wait.For those who think "exec" is evil: If the params are from an user input, you could be right. If the url is defined by your code, then its not.
Upvotes: 0
Reputation: 37
As request fire and forget. One of the solutions worked for me.
$client = new \GuzzleHttp\Client(['timeout' => 0.001]);
$promise = $client->requestAsync('GET', 'http://dummy.site');
try {
$promise->wait();
} catch (\Exception $ex) {
## Handle
}
If $promise->wait();
is not called the request was not performed.
Upvotes: -2
Reputation: 7851
If you don't care about the response, the following should do:
try {
$this->guzzle->post('http://myurl.com/doNotWait', ['timeout' => 1]);
} catch (\GuzzleHttp\Exception\ConnectException $e) {
// do nothing, the timeout exception is intended
}
So, here the request will take 1 sec and the code execution will continue.
Upvotes: 9
Reputation: 163
Make asynchronous call to create promise then call then() method with no callbacks
$client = new GuzzleClient();
$promise = $client->getAsync($url)
$promise->then();
Upvotes: -1
Reputation: 31068
To get it off the unanswered list:
Guzzle does not support "fire and forget" asynchronous requests without deep hacking.
The async methods are abstractions for Client::requestAsync()
, which returns a promise. See https://github.com/guzzle/promises#synchronous-wait - calling Promise::wait()
"is used to synchronously force a promise to complete".
Reference: https://github.com/guzzle/guzzle/issues/1429#issuecomment-197119452
Upvotes: 13