Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

blocking => false not working #826

Open
peixotorms opened this issue Aug 25, 2023 · 4 comments
Open

blocking => false not working #826

peixotorms opened this issue Aug 25, 2023 · 4 comments

Comments

@peixotorms
Copy link

peixotorms commented Aug 25, 2023

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

@schlessera
Copy link
Member

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

@peixotorms
Copy link
Author

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

@emohamed
Copy link

emohamed commented Apr 3, 2024

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

@schlessera
Copy link
Member

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants