简体   繁体   中英

amphp libary works on xampp but not on my webhoster

i want to execute domains in an array parallel. It works but only by xampp and not on my webhost. Why?

I use this:

https://github.com/amphp/parallel

Code:

<?php

require __DIR__ . '/../vendor/autoload.php';

use Amp\Parallel\Worker;
use Amp\Promise;

$urls = [
    'https://secure.php.net',
    'https://amphp.org',
    'https://github.com',
];

$promises = [];
foreach ($urls as $url) {
    $promises[$url] = Worker\enqueueCallable('file_get_contents', $url);
}

$responses = Promise\wait(Promise\all($promises));

foreach ($responses as $url => $response) {
    \printf("Read %d bytes from %s\n", \strlen($response), $url);
}

?>

Error Code If I run it on my webhoster:

Worker in pool exited unexpectedly with code -1 Line 250 on vendor/amphp/parallel/lib/Worker/DefaultPool.php Worker in pool exited unexpectedly with code -1 Line 250 on

Fatal error: Uncaught Amp\\Process\\ProcessException: Unable to list open file descriptors in /kunden/559288_442/webseiten/webhoster/parallel/vendor/amphp/process/lib/Internal/Posix/Runner.php:142 Stack trace: #0 /kunden/559288_442/webseiten/webhoster/parallel/vendor/amphp/process/lib/Internal/Posix/Runner.php(88): Amp\\Process\\Internal\\Posix\\Runner->generateFds() #1 /kunden/559288_442/webseiten/webhoster/parallel/vendor/amphp/process/lib/Process.php(108): Amp\\Process\\Internal\\Posix\\Runner->start('{ ('/usr/bin/ph...', '', Array, Array) #2 [internal function]: Amp\\Process\\Process->Amp\\Process{closure}() #3 /kunden/559288_442/webseiten/webhoster/parallel/vendor/amphp/amp/lib/Coroutine.php(67): Generator->current() #4 /kunden/559288_442/webseiten/webhoster/parallel/vendor/amphp/amp/lib/functions.php(96): Amp\\Coroutine->__construct(Object(Generator)) #5 /kunden/559288_442/webseiten/webhoster/parallel/vendor/amphp/process/lib/Process.php(110): Amp\\call(Object(Closure)) #6 /kunden/4 in /kunden/ 559288_442/webseiten/webhoster/parallel/vendor/amphp/parallel/lib/Context/Process.php on line 202

Based on the information provided, your user with on the web host's server doesn't have the required permissions to read the paths that Amp reads to find the file descriptors. Kind of an oversight.

As far as I can tell (from reading the Amp source code) creating a process is kind of a last resort when your web host does not support threads, which is going to be pretty much standard for all the shared hosting providers.

Use reactphp/filesystem to read files async. I have been able to use it successfully on shared hosting in the past even though it too creates child processes. Fortunately it creates them is such a way that doesn't need to access directories that are usually protected on shared hosting environments.

<?php

require dirname(__DIR__) . '/vendor/autoload.php';

// With Amp loop;
// $loop = new Amp\ReactAdapter\ReactAdapter((new Amp\Loop\DriverFactory)->create());

// With React EventLoop;
$loop = \React\EventLoop\Factory::create();

$filesystem = \React\Filesystem\Filesystem::create($loop);

// This returns a react/promise, which can be yielded in amp coroutines
$filesystem->file(__FILE__)->getContents()->then(function ($contents) {
    echo $contents, PHP_EOL;
}, function ($e) {
    echo $e->getMessage(), PHP_EOL;
});

// You only need this if you are running outside of an Amp Loop.
$loop->run();

You can pair reactphp/filesystem with amphp/react-adapter to share a single loop between the libraries.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM