#php #asynchronous #parallel-processing #amphp
#php #асинхронный #параллельная обработка #amphp
Вопрос:
я хочу параллельно выполнять домены в массиве. Это работает, но только на xampp, а не на моем веб-хостинге. Почему?
Я использую это:
https://github.com/amphp/parallel
Код:
<?php
require __DIR__ . '/../vendor/autoload.php';
use AmpParallelWorker;
use AmpPromise;
$urls = [
'https://secure.php.net',
'https://amphp.org',
'https://github.com',
];
$promises = [];
foreach ($urls as $url) {
$promises[$url] = WorkerenqueueCallable('file_get_contents', $url);
}
$responses = Promisewait(Promiseall($promises));
foreach ($responses as $url => $response) {
printf("Read %d bytes from %sn", strlen($response), $url);
}
?>
Код ошибки, если я запускаю его на своем веб-хостере:
Рабочий в пуле неожиданно вышел с кодом -1 Строка 250 на vendor/amphp/parallel/lib/Worker/DefaultPool.php Рабочий в пуле неожиданно вышел с кодом -1 Строка 250 на
Неустранимая ошибка: неперехваченный Amp ProcessProcessException: невозможно перечислить дескрипторы открытых файлов в /kunden/559288_442/webseiten/webhoster/parallel/vendor/amphp/process/lib/Internal/Posix/Runner.php:142 Трассировка стека: #0 /kunden/559288_442/webseiten/webhoster/parallel/vendor/amphp/process/lib/Internal/Posix/Runner.php(88) : УсилительПроцессInternal Posix Runner-> generateFds() #1 /kunden/559288_442/webseiten/webhoster/parallel/vendor/amphp/process/lib/Process.php (108): AmpProcessInternalPosixRunner->start(‘{ (‘/usr/bin/ph…’, «, Массив, Массив) #2 [внутренняя функция]: AmpProcessProcess-> Amp Process{closure}() #3 /kunden/559288_442/webseiten/webhoster/parallel/vendor/amphp/amp/lib/Coroutine.php (67): Генератор-> ток() #4 /kunden/559288_442/webseiten/webhoster/parallel/vendor/amphp/amp/lib/functions.php (96): Amp Сопрограмма->__построить(объект(генератор)) #5 /kunden/559288_442/webseiten/webhoster/parallel/vendor/amphp/process/lib/Process.php (110): Ampвызов(Объект (закрытие)) #6 / kunden / 4 в /kunden/559288_442/webseiten/webhoster/parallel/vendor/amphp/parallel/lib/Context/Process.php на линии 202
Ответ №1:
На основании предоставленной информации у вашего пользователя на сервере веб-хостинга нет необходимых разрешений для чтения путей, которые Amp считывает для поиска файловых дескрипторов. Своего рода оплошность.
Насколько я могу судить (из чтения исходного кода Amp), создание процесса является своего рода последним средством, когда ваш веб-хост не поддерживает потоки, что будет в значительной степени стандартным для всех провайдеров общего хостинга.
Используйте reactphp / filesystem для асинхронного чтения файлов. В прошлом я мог успешно использовать ее на общем хостинге, хотя она тоже создает дочерние процессы. К счастью, он создает их таким образом, что не требует доступа к каталогам, которые обычно защищены в средах общего хостинга.
<?php
require dirname(__DIR__) . '/vendor/autoload.php';
// With Amp loop;
// $loop = new AmpReactAdapterReactAdapter((new AmpLoopDriverFactory)->create());
// With React EventLoop;
$loop = ReactEventLoopFactory::create();
$filesystem = ReactFilesystemFilesystem::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();
Вы можете соединить reactphp / filesystem с amphp / react-adapter для совместного использования одного цикла между библиотеками.