简体   繁体   English

amphp 自动加载 class 未按预期工作

[英]amphp auto-load class not working as expected

I'm trying to use a custom class in a worker using amphp but it doesn't seem to be working.我正在尝试在使用 amphp 的工作人员中使用自定义 class ,但它似乎不起作用。 The below class is already auto-loaded using composer.下面的 class 已经使用 composer 自动加载。 Please help me out with this issue.请帮我解决这个问题。 My code is below:我的代码如下:

Class (this implements Task as mentioned on their docs): Class(这实现了他们文档中提到的任务):

<?php

namespace Jobs;

require '/home/xxx/vendor/autoload.php';

use Amp\Parallel\Worker\Environment;
use Amp\Parallel\Worker\Task;

class GetMarketJob implements Task {
    /**
     * @var callable
     */
    private $function;
    /**
     * @var mixed[]
     */
    private $args;

    public function __construct($function, ...$args) {
        $this->function = $function;
        $this->args = $args;
    }

    /**
     * {@inheritdoc}
     */
    public function run(Environment $environment)
    {
        if ($this->function instanceof \__PHP_Incomplete_Class) {
            throw new \Error('When using a class instance as a callable, the class must be autoloadable');
        }

        if (\is_array($this->callable) && ($this->callable[0] ?? null) instanceof \__PHP_Incomplete_Class) {
            throw new \Error('When using a class instance method as a callable, the class must be autoloadable');
        }

        if (!\is_callable($this->function)) {
            $message = 'User-defined functions must be autoloadable (that is, defined in a file autoloaded by composer)';
            if (\is_string($this->function)) {
                $message .= \sprintf("; unable to load function '%s'", $this->function);
            }

            throw new \Error($message);
        }

        return ($this->function)(...$this->args);
    }

    public function testMe($url = NULL) {
        $test = file_get_contents($url);
        return $test;
    }    
}

File using amphp to assign worker using above class:使用 amphp 分配使用上述 class 的工人的文件:

    <?php

require '/home/xxxx/vendor/autoload.php';

use Jobs\GetMarketJob;
// Example async producer using promisor

use Amp\Parallel\Worker;
use Amp\Promise;
use Amp\Loop;
use Amp\Parallel\Worker\DefaultPool;
use Amp\Parallel\Worker\Task;
use Amp\Parallel\Worker\Environment;
use Amp\Parallel\Worker\TaskFailureError;
use Amp\Parallel\Worker\DefaultWorkerFactory;

Amp\Loop::run(function () {
    $factory = new DefaultWorkerFactory();

    $worker = $factory->create();

    $result = yield $worker->enqueue(new GetMarketJob('testMe', ['https://www.syhtek.com']));
    
    print($result);

    $code = yield $worker->shutdown();
    \printf("Code: %d\n", $code);
});

running this script gives me the below output:运行这个脚本给了我下面的 output:

[26-May-2021 01:23:11 UTC] PHP Fatal error: Uncaught Amp\Parallel\Worker\TaskFailureError: Uncaught Error in worker with message "User-defined functions must be autoloadable (that is, defined in a file autoloaded by composer); unable to load function 'testMe'" and code "0"; [26-May-2021 01:23:11 UTC] PHP 致命错误:未捕获的 Amp\Parallel\Worker\TaskFailureError:工作人员中未捕获的错误,并显示消息“用户定义的函数必须是可自动加载的(即,在由作曲家);无法加载 function 'testMe'”和代码“0”; use Amp\Parallel\Worker\TaskFailureError::getOriginalTrace() for the stack trace in the worker in /home/xxxx/vendor/amphp/parallel/lib/Worker/Internal/TaskFailure.php:60使用 Amp\Parallel\Worker\TaskFailureError::getOriginalTrace() 在 /home/xxxx/vendor/amphp/parallel/lib/Worker/Internal/TaskFailure.php:60 中的工作人员中的堆栈跟踪

Thank you so much for reading!非常感谢您的阅读!

The issue here is that you're passing 'testMe' and then check if (!\is_callable($this->function)) { , while it should be if (,\method_exists($this, $this->function)) { .这里的问题是你通过'testMe'然后检查if (!\is_callable($this->function)) { ,而它应该是if (,\method_exists($this, $this->function)) { .

And return ($this->function)(...$this->args);return ($this->function)(...$this->args); should be return ($this->{$this->function})(...$this->args);应该是return ($this->{$this->function})(...$this->args); if you're trying to call that method.如果您尝试调用该方法。 You might also call that method directly instead of giving it to the constructor.您也可以直接调用该方法,而不是将其提供给构造函数。

If everything you do in the worker is an HTTP request, you should look into amphp/http-client instead of amphp/parallel , as non-blocking I/O is much more efficient than several chlid processes with blocking I/O.如果你在 worker 中所做的一切都是 HTTP 请求,你应该查看amphp/http-client而不是amphp/parallel ,因为非阻塞 I/O 比几个具有阻塞 I/O 的 chlid 进程更有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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