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

Basic question 'bout reactphp #58

Closed
RobertEcker opened this issue Jul 6, 2022 · 9 comments
Closed

Basic question 'bout reactphp #58

RobertEcker opened this issue Jul 6, 2022 · 9 comments
Labels
question Further information is requested

Comments

@RobertEcker
Copy link

RobertEcker commented Jul 6, 2022

Hi,

Sorry, for this - again - basic question about reactphp

To make my question more clear, I use this DNS lookup example:

<?php
$result = [];
$domains = ['domain1.com', 'domain2.xyz'];

foreach ($domains as $domain) {
    $result[] = dns_get_record($domain);
}

var_dump($result);

Can above example executed in parallel (to make it faster) with reactphp or not (and if yes, how with async? or event-loop? can you give me an additional hint)?
If I understand this stackoverflow post correctly, it can not (but I do not think so).

Thank you again.

@WyriHaximus
Copy link
Member

That's easy, use react/dns

@RobertEcker
Copy link
Author

RobertEcker commented Jul 6, 2022

Hi @WyriHaximus,

I know react/dns ... DNS was just an example ... it is more about a general question: how to execute own functions etc. in parallel with reactphp

@WyriHaximus
Copy link
Member

Keep in mind that non of these functions can block, you'd still have to use non-blocking I/O functions for anything you do in here, but it comes down to:

$promises = [];
foreach (range(1, 13) as $i) {
    $promises[] = (async(function (int $i) {
        return $i;
    }))($i);
}

var_export(await($promises));

@RobertEcker
Copy link
Author

thank you for the example
regarding "non of these functions can block": i do not fully understand because "dns_get_record" (in my example) blocks the next one/ones (because of waiting of the response) - or did you mean your example (then it is clear)

@WyriHaximus
Copy link
Member

I meant functions like dns_get_record will block the event loop and thus everything else running in it. Which is why I suggested using react/dns. Let me rewrite your initial code with it, maybe that's clearer:

<?php
$result = [];
$domains = ['domain1.com', 'domain2.xyz'];

foreach ($domains as $domain) {
    $result[] = (async(function (string $domain) {
        return await($dns->resolve(domain));
    }))(domain);
}

var_dump(await($result));

That could be done simpler like this:

<?php
$result = [];
$domains = ['domain1.com', 'domain2.xyz'];

foreach ($domains as $domain) {
    $result[] = $dns->resolve(domain);
}

var_dump(await($result));

@RobertEcker
Copy link
Author

Thank you again @WyriHaximus

That means the stackoverflow-post is correct? So reactphp is not forking processes to make it faster in general?

@RobertEcker
Copy link
Author

ok maybe i should check react/dns how it is done there to make it possible for all functions?

@WyriHaximus
Copy link
Member

We provide react/child-process to do such things, and I have a package or two allowing you to use child processes to run functions outside the current process. But that is not performant compared to staying in the current process alternatives that hook directly into the event loop.

The whole goal of reactphp is doing these things non-blocking at such a speed it looks like they are run in parallel.

@clue clue added the question Further information is requested label Jul 6, 2022
@clue
Copy link
Member

clue commented Jul 6, 2022

As @WyriHaximus pointed out, you can execute all blocking functions in a separate child process to avoid blocking the main process. For instance, you can use https://github.com/clue/reactphp-pq to execute the dns_get_record() function like this:

$executor = new Clue\React\Pq\Executor();
$dns_get_record = $executor->fun('dns_get_record');

$dns_get_record($domain)->then(function ($result) {
    var_dump($result);
}, function (Exception $e) {
    echo 'Error: ' . $e->getMessage() . PHP_EOL;
});

That said, I agree that this should usually be used as a last resort only as execution in child processes incurs some noticeable overhead (YMMV). For many common APIs, ReactPHP provides async alternatives that are implemented in pure PHP (see https://github.com/reactphp/reactphp/wiki/Users). For DNS queries, this would be the DNS component as suggested above.

I believe this has been answered, so I'm closing this for now. Please come back with more details if this problem persists and we can always reopen this 👍

@clue clue closed this as completed Jul 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants