swoft-cloud / swoft

🚀 PHP Microservice Full Coroutine Framework
https://swoft.org
Apache License 2.0
5.58k stars 786 forks source link

[Task]Task投递时配置coroutine=true不可用 #309

Closed JiankangMai closed 6 years ago

JiankangMai commented 6 years ago
Q A
Bug report? yes
Feature request? no
Swoft version swoftv1.0.20
Swoole version swoole4.0
PHP version PHP7.2
Runtime environment CentOS 6.8

文档没有提及@Task(Swoft\Task\Bean\Annotation\Task)的参数coroutine,但是根据源码,是支持该参数的。 该参数默认为false,配置为true时,任务执行器会通过Swoft\Task\TaskExecutor->runCoTask()执行该任务。但是由于Task进程/onTask()中不可使用协程,总是是抛出Swoole\Coroutine::create(): can't use async-io in task process.错误。

报错Task配置示例

/**
 * @Task(name="TaskXXXXXX",coroutine=true)
 */
class XXXXXXTask
{
}

框架源码

/**
 * The listener of swoole task
 * @SwooleListener({
 *     SwooleEvent::ON_TASK,
 *     SwooleEvent::ON_FINISH,
 * })
 */
class TaskEventListener implements TaskInterface, FinishInterface
{
    public function onFinish(Server $server, int $taskId, $data)
    {
        App::trigger(TaskEvent::FINISH_TASK, $taskId, $data);
    }

    /**
     * @param \Swoole\Server $server
     * @param int            $taskId
     * @param int            $workerId
     * @param mixed          $data
     * @return mixed
     * @throws \InvalidArgumentException
     */
    public function onTask(Server $server, int $taskId, int $workerId, $data)
    {
        try {
            /* @var TaskExecutor $taskExecutor*/
            $taskExecutor = App::getBean(TaskExecutor::class);
            $result = $taskExecutor->run($data);
        } catch (\Throwable $throwable) {
            App::error(sprintf('TaskExecutor->run %s file=%s line=%d ', $throwable->getMessage(), $throwable->getFile(), $throwable->getLine()));
            $result = false;

            // Release system resources
            App::trigger(AppEvent::RESOURCE_RELEASE);

            App::trigger(TaskEvent::AFTER_TASK);
        }
        return $result;
    }
}
    /**
     * @param string $data
     *
     * @return mixed
     */
    public function run(string $data)
    {
        $data = TaskHelper::unpack($data);

        $name   = $data['name'];
        $type   = $data['type'];
        $method = $data['method'];
        $params = $data['params'];
        $logid  = $data['logid'] ?? uniqid('', true);
        $spanid = $data['spanid'] ?? 0;

        $collector = TaskCollector::getCollector();
        if (!isset($collector['task'][$name])) {
            return false;
        }

        list(, $coroutine) = $collector['task'][$name];
        $task = App::getBean($name);
        if ($coroutine) {
            $result = $this->runCoTask($task, $method, $params, $logid, $spanid, $name, $type);
        } else {
            $result = $this->runSyncTask($task, $method, $params, $logid, $spanid, $name, $type);
        }

        return $result;
    }
JiankangMai commented 6 years ago

Swoole.Task是支持协程投递但是不支持协程执行的,后续会去掉该参数还是修改该参数的含义?

JiankangMai commented 6 years ago

额.....看到文档的说明了,该参数暂时不可用