一:Task任务:
1、配置,在 app/bean.php文件中加入
'httpServer' => [
// ...
'on' => [
SwooleEvent::TASK => \bean(TaskListener::class), // Enable task must task and finish event
SwooleEvent::FINISH => \bean(FinishListener::class)
],
/* @see HttpServer::$setting */
'setting' => [
'task_worker_num' => 12,
'task_enable_coroutine' => true,
'worker_num' => 2
]
],
2、定时任务
1、安装 composer require swoft/crontab 2、配置
'httpServer' => [
// ...
'process' => [
'crontab' => bean(Swoft\Crontab\Process\CrontabProcess::class)
],
// ...
],
3、定义,在/app/Task/Crontab/ 文件夹中新建文件
<?php
namespace App\Task\Crontab;
use Swoft\Crontab\Annotaion\Mapping\Cron;
use Swoft\Crontab\Annotaion\Mapping\Scheduled;
/**
* Class DemoCronTask
* @package App\Task\Crontab
*
* @Scheduled(name="demoCronTask") //声明定时任务
*/
class DemoCronTask{
/**
* @Cron("*") //每秒执行
*/
public function secondTask(){
var_dump("--111----",date('Y-m-d H:i:s', time()));
}
/**
* @Cron("0 * * * * *") //每分钟执行
*/
public function miunteTask(){
var_dump("222------",date('Y-m-d H:i:s', time()));
}
}
3、协程、异步任务
(1)、声明一个任务,在 /app/Task/Task/ 文件夹新建文件
<?php declare(strict_types=1);
namespace App\Task\Task;
use Swoft\Task\Annotation\Mapping\Task;
use Swoft\Task\Annotation\Mapping\TaskMapping;
/**
* Class DemoTask
*
* @since 2.0
* @Task(name="demoV2Task") //标记类是一个任务
*/
class DemoTask
{
/**
* @TaskMapping(name="list") //映射名称
*
* @param int $id
* @param string $default
*
* @return array
*/
public function getList(int $id): array
{
var_dump("------------");
sleep(5);
return [
'list' => [1, 3, 3],
'id' => $id
];
}
/**
* @param int $id
* @return bool
*
* @TaskMapping(name="putLists")
*/
public function putList(int $id) : bool
{
if($id > 5)
return true;
return false;
}
}
(2)、任务投递
// 协程投递
$data = Task::co('demoV2Task', 'list', [12]);
//异步投递
$data = Task::async('demoV2Task', 'list', [12]);
(3)、异步投递如果需要关注异步任务处理结果,可以添加监听器,在文件夹 /app/Task/Listener/ 下新建文件
<?php
namespace App\Task\Listener;
use Swoft\Log\Helper\CLog;
use function context;
use Swoft\Event\Annotation\Mapping\Listener;
use Swoft\Event\EventHandlerInterface;
use Swoft\Event\EventInterface;
use Swoft\Task\TaskEvent;
/**
* Class DemoListener
* @package App\Task\Listener
* @Listener(event=TaskEvent::FINISH) //参数必须带Finsh
*/
class DemoListener implements EventHandlerInterface{
/**
* @param EventInterface $event
*
* @throws \Swoft\Exception\SwoftException
*/
public function handle(EventInterface $event): void
{
// TODO: Implement handle() method.
$fId = context()->getTaskUniqid();
// var_dump($fId);
CLog::info(\context()->getTaskUniqid());
$taskData = context()->getTaskData();
// var_dump($taskData);
CLog::info(\context()->getTaskData());
}
}
二:协程 : https://www.bookstack.cn/read/swoft-doc-v2.x/common-co.md
use Swoft\Co;
//创建一个协程
Co::create(function(){
// to do
sleep(3);
var_dump("--2222----");
});
//并发
$request = [
'method' => function () {
sleep(8);
return "111";
},
'staticMethod' => function () {
sleep(5);
return "2222";
},
'closure' => function () {
sleep(2);
return "3333";
}
];
$resd = Co::multi($request);//同时执行,同步,会阻塞
注意:Task中有两个地方还未清楚
- 协程投递任务时是阻塞( $data = Task::co('demoV2Task','list',[2],10); )。
- 使用 Co::multi() 执行并发时会阻塞。
- 异步监听的地方,所有监听器只有带了参数 @Listener(event=TaskEvent::FINISH) 都会执行一遍。