amphp / parallel-functions

Simplified parallel processing for PHP based on Amp.
https://amphp.org/parallel-functions
MIT License
271 stars 18 forks source link

Multiple errors encountered #10

Closed arvindkalbhor closed 5 years ago

arvindkalbhor commented 6 years ago

I want to use file_get_html() as parrallel but its giving error like "Multiple errors encountered"

Here is code :

$responses = wait(parallelMap([ 'https://google.com/', 'https://github.com/', 'https://stackoverflow.com/', ], function ($url) { return file_get_html($url); }));

kelunik commented 6 years ago

What does $exception->getReasons() say if you catch it?

reimax commented 6 years ago

I also faced a similar problem and did not find in the documentation how to solve it. I'm trying to use parallel-functions in my project. I have a static method in a class where I need to do multiple operations at the same time. my code:

$values = wait(parallelMap($parallel_map, function ($url) { return test_test($url); })); in $parallel_map i have url array. test_test - my test function. I also tried using a static class method instead of my function and it didn't work either.

kelunik commented 6 years ago

Do you use environment variables in the code executed by the parallel worker? What does getReasons() report (see above)?

reimax commented 6 years ago
function file_get_html($test) {
    return "test";
}
require_once '/vendor/parallel/vendor/autoload.php';
use function Amp\ParallelFunctions\parallelMap;
use function Amp\Promise\wait;

try {
    $responses = wait(parallelMap([
        'https://google.com/',
        'https://github.com/',
        'https://stackoverflow.com/',
        ], function ($url) {
            return \file_get_html($url);
    }));
} catch (Exception $exception) {
    dd($exception->getReasons());
    exit;
}

getReasons report: https://codeshare.io/5Oz1j7

kelunik commented 6 years ago

file_get_html doesn't exist in the worker, that should probably be file_get_contents?

reimax commented 6 years ago

in my code, I'm trying to call a function that was previously declared. not file_get_contents(). this is example. Is it possible to do this?

kelunik commented 6 years ago

The function needs to be loaded by Composers autoloader, so it must be in a file listed in the "files" autoloader directive.

reimax commented 6 years ago

what's the easiest way? if I need to use 3-4 functions that lie in 3-4 files and 1-2 methods in different classes, I will need to constantly add them to it? It is a pity, this library will have to be abandoned.

kelunik commented 6 years ago

You can also manually require the file defining the functions. Methods in classes should be autoloaded automatically if you use Composer for that.

How do you normally ensure your functions are defined at the place where you use them?

reimax commented 6 years ago

I use composter for third-party libraries. To load my class I'm using 'nette/robotloader'.

I gave an example of the code, do I understand correctly what I need before return \file_get_html ($url); connect the file with the desired function. That is, in my example, I connect the same class in which there is a call to this library?

kelunik commented 6 years ago

What do you mean with connect? Maybe you can publish a small sample repository for me to reproduce the problem?

reimax commented 6 years ago

so I gave an example above. composer is used to load third-party libraries, a set of classes written by me is not designed as a package for composer, because it's just not necessary. my classes are loaded using the loader specified above. In the example above, I specified a code sample in a single file. just imagine that instead of one file I have 5 classes with my own logic.

connect ////example from RobotLoader repo///// $obj = new BaseClass(); $test = $obj->blablabla();

kelunik commented 6 years ago

A function definition in the same file won't work, because the file needs to be autoloadable by Composer. The workers don't share the PHP interpreter instance, but each one has their own interpreter instance.

By structuring your package as a Composer package itself, you get the autoloading for free. The only thing you need is adding an "autoload" section to your composer.json.

sayanb commented 5 years ago

I have the same problem. My code

try {
    $responses = wait(parallelMap([
        'https://google.com/',
        'https://github.com/',
        'https://stackoverflow.com/',
    ], function ($url) {
        return executeTask($url);
    }));
} catch (Exception $ex) {
    print_r($ex->getReasons());
    //echo $ex->getMessage();
    exit;
}

At the beginning of this PHP file, I added a require 'path/to/child.php' and this child.php file has the definition of the executeTask() function. So essentially this is doing what was suggested above: You can also manually require the file defining the functions.

However, it still gives the same error as above.

kelunik commented 5 years ago

@sayanb In that case, you have to require it in the child, too, so inside your function ($url) { ... }.

sayanb commented 5 years ago

@kelunik thanks, that works!

kelunik commented 5 years ago

Cool!