Requests
Requests copied to clipboard
blocking => false not working
Summary
When I set blocking => false
, the request is still blocking.
Given the following code sample
# make options
$options = array(
'timeout' => 60,
'connect_timeout' => 10,
'blocking' => false
);
# request
$response = WpOrg\Requests\Requests::request($url, $headers, $data, POST, $options);
Unfortunately, if I set a short timeout like 1 second, the remote API call will not complete. I don't need the response, only for it to run in the background while the script does something else.
I'd expect the following behaviour
I would expect it to return immediately, so the rest of the script can run.
Instead this happened
With a long API call lasting over 1 minute, the script hangs until it returns a reply.
Additional context
The way around this for non blocking requests is to use curl with CURLOPT_NOSIGNAL
set to 1.
This let's me timeout early and the api call will complete properly.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $endpoint);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($fields));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 1); // Set timeout to 1 second
curl_setopt($ch, CURLOPT_NOSIGNAL, 1); // Ignore all cURL signals to ensure script continues
curl_exec($ch);
curl_close($ch);
Your environment
Environment | Answer |
---|---|
Operating system and version: | Ubuntu 22.04 |
PHP version | 8.2 lsapi, openlitespeed |
Requests version | v2.0.7 |
Tested against develop
branch?
no
@peixotorms I cannot replicate this. When using 'blocking' => false
, Requests bails early on a request with an empty Response
object. You can see this for example when checking that the 'status'
in the response is false
.
Can you provide more information or a piece of content that lets us replicate this?
Hi, it's been over 3 months, so I don't remember the exact case, but If I remember correctly, when you call an external url that takes for example 10 seconds to complete the output, it was also slowing down the response on the calling script, regardless of the blocking settings.
So script A calls script B with blocking = false, but script B needs 10 seconds to complete. Script A would then take at least 10 seconds to finish as well.
Adding CURLOPT_NOSIGNAL when blocking = false, sorted it for me though.
I'll test this again against the latest version soon, but not right now.
Thanks
@schlessera the problem is reproducible for me. It's apparent if you use an endpoint that takes longer to produce a response, like https://httpbin.org/delay/5:
$ wp eval --skip-wordpress '
$start = microtime(true);
$response = WpOrg\Requests\Requests::request( "https://httpbin.org/delay/5", [], [], "GET", [ "blocking" => false, "verify" => false ] );
print_r($response);
echo "Request took: " . (microtime(true) - $start ) . " seconds";'
WpOrg\Requests\Response Object
(
[body] =>
[raw] =>
[headers] => WpOrg\Requests\Response\Headers Object
(
[data:protected] => Array
(
)
)
[status_code] =>
[protocol_version] =>
[success] =>
[redirects] => 0
[url] =>
[history] => Array
(
)
[cookies] => WpOrg\Requests\Cookie\Jar Object
(
[cookies:protected] => Array
(
)
)
)
Request took: 5.6029760837555 seconds
The response is indeed empty, however the library is awaiting for it.
@peixotorms @emohamed Thanks, I can indeed replicate this.
Using CURLOPT_NOSIGNAL
can introduce other problems, though, as this means that cURL skips registering any signal handlers. The most obvious issue there will be that DNS timeouts will not be caught and just go on indefinitely, unless you catch these yourself.