首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将amphp/parallel库用于非阻塞进程

如何将amphp/parallel库用于非阻塞进程
EN

Stack Overflow用户
提问于 2019-05-14 21:32:23
回答 1查看 1.1K关注 0票数 1

我想使用amphp/parallel库来实现非阻塞进程。我有一个简单的下载文件功能,它对远程图像文件执行curl命中,并将其保存到本地。我通过REST API实现了这个方法。基本上我想要一个在后台进行aysnc下载的过程,可以这么说,REST API点击函数,函数说“嘿,好吧,我正在后台下载,你可以继续”。表示非阻塞,API得到的响应为ok,而不是等待。同时,如果下载过程中出现网络故障,工作人员可以在一段时间内重新启动该过程。我该如何开始?

我已经尝试了以下代码,但不起作用。

代码语言:javascript
复制
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是一个简单的下载函数

代码语言:javascript
复制
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;
}

我得到了这个错误:

代码语言:javascript
复制
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

对于后台运行的进程,我在How does amphp work中有类似的要求。

EN

回答 1

Stack Overflow用户

发布于 2019-06-14 14:13:00

一般来说,Amp并不能在后台神奇地工作。如果你通过PHP-FPM或类似的方式使用PHP,一旦响应完成,Amp就会关闭,就像其他任何东西一样。

如果你想把工作从这些请求转移到后台进程,你需要某种队列(例如beanstalkd)和一个(永久的)工作进程来处理这些排队的作业。您可以使用Amp编写这样一个守护进程的工作进程,但它必须在带外启动。

也就是说,如果你只是想要并发下载,amphp/artax比使用amphp/parallel更适合,因为与每个HTTP请求单独的PHP进程相比,它有一种更低的开销。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56131739

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档