Requests icon indicating copy to clipboard operation
Requests copied to clipboard

blocking => false not working

Open peixotorms opened this issue 1 year ago • 4 comments

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 avatar Aug 25 '23 15:08 peixotorms

@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.

image

Can you provide more information or a piece of content that lets us replicate this?

schlessera avatar Nov 09 '23 16:11 schlessera

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

peixotorms avatar Nov 10 '23 16:11 peixotorms

@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.

emohamed avatar Apr 03 '24 13:04 emohamed

@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.

schlessera avatar Apr 03 '24 16:04 schlessera