14. Task机制

一、用途

  • 现阶段 Swoole 暂时没有办法 hook 所有的阻塞函数,也就意味着有些函数仍然会导致 进程阻塞,从而影响协程的调度。
  • 此时我们可以通过使用 Task 组件来模拟协程处理,从而达到不阻塞进程调用阻塞函数的目的。
  • 本质上是仍是是多进程运行阻塞函数,所以性能上会明显地不如原生协程,具体取决于 Task Worker 的数量。

二、安装

composer require hyperf/task

三、配置

  • 文件:config/autoload/server.php
<?php
  
use Hyperf\Server\Event;

return [
    // 这里省略了其它不相关的配置项
    'settings' => [
        // Task Worker 数量,根据您的服务器配置而配置适当的数量
        'task_worker_num' => 8,
        // 因为 `Task` 主要处理无法协程化的方法,所以这里推荐设为 `false`,避免协程下出现数据混淆的情况
        'task_enable_coroutine' => false,
    ],
    'callbacks' => [
        // Task callbacks
        Event::ON_TASK => [Hyperf\Framework\Bootstrap\TaskCallback::class, 'onTask'],
        Event::ON_FINISH => [Hyperf\Framework\Bootstrap\FinishCallback::class, 'onFinish'],
    ],
];

四、使用

1. 使用注解

<?php
namespace App\Service;

use Hyperf\Coroutine\Coroutine;
use Hyperf\Task\Annotation\Task;

class TaskService
{
    #[Task]
    public function handle($cid)
    {
        return [
            'worker.cid' => $cid,
            // task_enable_coroutine 为 false 时返回 -1,反之 返回对应的协程 ID
            'task.cid' => Coroutine::id(),
        ];
    }
}
  • 调用
<?php
namespace App\Controller;

use App\Service\TaskService;
use Hyperf\Coroutine\Coroutine;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\AutoController;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\HttpServer\Contract\ResponseInterface;

#[AutoController]
class TaskController
{
    #[Inject]
    private TaskService $taskService;

    public function index(RequestInterface $request, ResponseInterface $response)
    {
        $result = $this->taskService->handle(Coroutine::id());

        return $response->json($result);
    }
}

2. 主动方法投递(不推荐)

<?php

use Hyperf\Coroutine\Coroutine;
use Hyperf\Context\ApplicationContext;
use Hyperf\Task\TaskExecutor;
use Hyperf\Task\Task;

class MethodTask
{
    public function handle($cid)
    {
        return [
            'worker.cid' => $cid,
            // task_enable_coroutine 为 false 时返回 -1,反之 返回对应的协程 ID
            'task.cid' => Coroutine::id(),
        ];
    }
}

// 使用
$container = ApplicationContext::getContainer();
$exec = $container->get(TaskExecutor::class);
$result = $exec->execute(new Task([MethodTask::class, 'handle'], [Coroutine::id()]));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值