异步任务
在服务启动后的任意一个地方,都可以进行异步任务的投递,为了简化异步任务的投递,框架封装了任务管理器,用于投递同步/异步任务,投递任务有两种方式,一是直接投递闭包,二是投递任务模板类
任务比较简单的情况下可以直接投递闭包,任意地方包括控制器/定时器/服务启动后的各种回调中均可进行投递
$a=1;//使用外部变量将不存在
TaskManager::async(function ($image,$a) {
var_dump($image);
var_dump($a);
$this->testFunction();//使用外部对象的引用将出错
return true;
},function () {});
当任务比较复杂,逻辑较多而且固定时,可以预先创建任务模板,并直接投递任务模板,以简化操作和方便在多个不同的地方投递相同的任务,首先需要创建一个任务模板
class Task extends \EasySwoole\EasySwoole\Swoole\Task\AbstractAsyncTask
{
/**
* 执行任务的内容
* @param mixed $taskData 任务数据
* @param int $taskId 执行任务的task编号
* @param int $fromWorkerId 派发任务的worker进程号
* @author : evalor <master@evalor.cn>
*/
function run($taskData, $taskId, $fromWorkerId,$flags = null)
{
// 每个worker进程的编号都是从0开始
// 所以 $fromWorkerId + $taskId 才是绝对唯一的编号
// !!! 任务完成需要 return 结果
}
/**
* 任务执行完的回调
* @param mixed $result 任务执行完成返回的结果
* @param int $task_id 执行任务的task编号
* @author : evalor <master@evalor.cn>
*/
function finish($result, $task_id)
{
// 任务执行完的处理
}
}
然后同上例,一样可以在服务启动后的任何地方进行投递,只是将闭包换成任务模板类的实例进行投递
可通过继承EasySwoole\EasySwoole\Swoole\Task\QuickTaskInterface
,增加run方法,即可实现一个任务模板,通过直接投递类名运行任务:
<?php
namespace App\Task;
use EasySwoole\EasySwoole\Swoole\Task\QuickTaskInterface;
class QuickTaskTest implements QuickTaskInterface
{
static function run(\swoole_server $server, int $taskId, int $fromWorkerId,$flags = null)
{
echo "快速任务模板";
}
$result = TaskManager::async(\App\Task\QuickTaskTest::class);
由于自定义进程的特殊性,不能直接调用Swoole的异步任务相关方法进行异步任务投递,框架已经封装好了相关的方法方便异步任务投递,请看下面的例子
有时需要同时执行多个异步任务,最典型的例子是数据采集,采集完多个数据后集中进行处理,这时可以进行并发任务投递,底层会将任务逐个进行投递并执行,所有任务执行完后返回一个结果集
// 多任务并发
$tasks[] = function () { sleep(50000);return 'this is 1'; }; // 任务1
$tasks[] = function () { sleep(2);return 'this is 2'; }; // 任务2
$tasks[] = function () { sleep(50000);return 'this is 3'; }; // 任务3
$results = \EasySwoole\EasySwoole\Swoole\Task\TaskManager::barrier($tasks, 3);
var_dump($results);
/**
* 投递一个异步任务
* @param mixed $task 需要投递的异步任务
* @param mixed $finishCallback 任务执行完后的回调函数
* @param int $taskWorkerId 指定投递的Task进程编号 (默认随机投递给空闲进程)
* @return bool 投递成功 返回整数 $task_id 投递失败 返回 false
*/
static function async($task,$finishCallback = null,$taskWorkerId = -1)
/**
* 异步进程内投递任务
* @param array $taskList 需要执行的任务列表
* @param float $timeout 任务执行超时
* @return array|bool 每个任务的执行结果
*/
static function barrier(array $taskList, $timeout = 0.5)