Как использовать библиотеку ampphp/parallel для неблокирующего процесса

Я хочу использовать библиотеку amphp/parallel для неблокирующего процесса. У меня есть простая функция загрузки файла, которая закручивает удаленный файл изображения и сохраняет его на локальном компьютере. Я использую этот метод через REST API. По сути, мне нужен процесс, в котором загрузка aysnc должна выполняться на бэкэнде, и можно сказать, что REST API использует функцию, а функция говорит: «Эй, хорошо, я загружаю в фоновом режиме, вы можете продолжить». Означает неблокирующий и API получает ответ как ok , чтобы не ждать. Между тем, если при загрузке произойдет какой-либо сбой в сети, рабочий может перезапустить процесс через некоторое время. Как мне начать?

Я пробовал следующий код, но не работал.

require_once "vendor/autoload.php";
use Amp\Loop;
use Amp\Parallel\Worker\CallableTask;
use Amp\Parallel\Worker\DefaultWorkerFactory;

\Amp\Loop::run(function () {
  $remote_file_url = "some remote image url"; //http://example.com/some.png
  $file_save_path = "save path for file"; //var/www/html/some.png
  $factory = new DefaultWorkerFactory();
  $worker = $factory->create();
  $result = yield $worker->enqueue(new CallableTask('downloadFile', [$remote_file_url, $file_save_path]));

  $code = yield $worker->shutdown();

  });

//downloadFile — это простая функция загрузки

function downloadFile($remoteFile, $localFile) {
    if (!$remoteFile || !$localFile) {
        return;
    }
    set_time_limit(0);
    $fp = fopen($localFile, 'w+');
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $remoteFile);
    curl_setopt($ch, CURLOPT_TIMEOUT, 50);
    curl_setopt($ch, CURLOPT_FILE, $fp);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    $result = curl_exec($ch);
    curl_close($ch);
    fclose($fp);

    return $result ? true : false;
}

Я получаю эту ошибку:

PHP Fatal error:  Uncaught Amp\\Parallel\\Worker\\TaskError: Uncaught Error in worker with message "Call to undefined function downloadFile()" and code "0" in /var/www/html/test/vendor/amphp/parallel/lib/Worker/Internal/TaskFailure.php:45\nStack trace:\n#0 /var/www/html/test/vendor/amphp/parallel/lib/Worker/TaskWorker.php(126): Amp\\Parallel\\Worker\\Internal\\TaskFailure->promise()\n#1 [internal function]: Amp\\Parallel\\Worker\\TaskWorker->Amp\\Parallel\\Worker\\{closure}()\n#2 /var/www/html/test/vendor/amphp/amp/lib/Coroutine.php(76): Generator->send(Object(Amp\\Parallel\\Worker\\Internal\\TaskFailure))\n#3 /var/www/html/test/vendor/amphp/amp/lib/Internal/Placeholder.php(130): Amp\\Coroutine->Amp\\{closure}(NULL, Object(Amp\\Parallel\\Worker\\Internal\\TaskFailure))\n#4 /var/www/html/test/vendor/amphp/amp/lib/Coroutine.php(81): Amp\\Coroutine->resolve(Object(Amp\\Parallel\\Worker\\Internal\\TaskFailure))\n#5 /var/www/html/test/vendor/amphp/amp/lib/Internal/Placeholder.php(130): Amp\\Coroutine->Amp\\{closure}(NULL, Object(Amp\\Parallel\\Worker\\Internal\\TaskFailur in /var/www/html/test/vendor/amphp/parallel/lib/Worker/Internal/TaskFailure.php on line 45

У меня есть такое же требование, как задано в Как работает amphp в отношении фонового процесса.


person Neeraj Krishna Maurya    schedule 14.05.2019    source источник
comment
Пожалуйста, добавьте более подробную информацию о том, что вы пробовали, почему это не сработало и чего вы ожидали, см. stackoverflow.com/help/mcve   -  person CoderJoe    schedule 14.05.2019


Ответы (1)


Как правило, усилитель не работает волшебным образом в фоновом режиме. Если вы используете PHP через PHP-FPM или подобное, Amp будет закрыт после завершения ответа, как и все остальное.

Если вы хотите переместить работу из этих запросов в фоновые процессы, вам нужна какая-то очередь (например, beanstalkd) и (постоянный) рабочий процесс для обработки этих заданий в очереди. Вы можете написать такой демонизированный воркер с помощью Amp, но его придется запускать вне диапазона.

Тем не менее, если вам просто нужны одновременные загрузки, amphp/artax лучше подходит, чем использование amphp/parallel, поскольку у него есть способ более низкие накладные расходы по сравнению с отдельным процессом PHP для каждого HTTP-запроса.

person kelunik    schedule 14.06.2019
comment
Я понимаю, что вы говорите. Не могли бы вы подсказать мне, как создать Worker с помощью amphp/parallel и одновременно поставить его в очередь с помощью beanstalkd? Как с ним создать очередь? - person Neeraj Krishna Maurya; 17.10.2019