# 4.5 同步任務
同步任務即Task,用來做一些異步的慢速任務,比如發郵件、批量任何、任何不支持異步Client的服務調用等等。MSF框架是純異步Server架構,也就是說任何耗時的任務的代碼不能放到Worker進程中執行,所以我們利用Swoole的Task模塊來完成耗時任務。
## Task進程
同步任務代碼是在Task進程中執行的,Task進程具有以下的特性:
- 同步阻塞
- 支持定時器
目前MSF框架封裝了異步的Http Client、Redis Client、MySQL Client,除了這幾種原生支持異步外,任何其他的非異步Client的網絡IO均要封裝成Task,比如MongoDB Task。
## Task示例
框架內封裝了Task基類`\PG\MSF\Tasks\Task`,自定義的Task都應該繼承此類。另外,框架內置一個MongoDbTask類,是操作MongoDB的任務類,封裝了查詢和修改MongoDB數據庫的一些基本方法,如:
### composer安裝依賴
編輯項目的composer.json,加入依賴`alcaeus/mongo-php-adapter`
```json
{
"require": {
"alcaeus/mongo-php-adapter": "^1.0"
}
}
```
或者
```bash
$composer require alcaeus/mongo-php-adapter
```
### MongoDB配置
```php
<?php
/**
* MongoDb配置文件
*
* @author camera360_server@camera360.com
* @copyright Chengdu pinguo Technology Co.,Ltd.
*/
$config['mongodb']['test']['server'] = 'mongodb://192.168.1.106:27017';
$config['mongodb']['test']['options'] = ['connect' => true];
$config['mongodb']['test']['driverOptions'] = [];
return $config;
```
示例代碼:
[./php-msf-demo/config/docker/mongodb.php](https://github.com/pinguo/php-msf/pinguo/config/docker/mongodb.php)
### Task業務邏輯類
```php
<?php
namespace App\Tasks;
use \PG\MSF\Tasks\MongoDbTask;
class Idallloc extends MongoDbTask
{
/**
* 當前要用的配置 配置名,db名,collection名
* @var array
*/
protected $mongoConf = ['test', 'demo', 'idalloc'];
public function getNextId($key)
{
$condition = [
'_id' => $key,
];
$update = [
'$inc' => [
'last' => 1,
],
];
$options = [
'new' => true,
'upsert' => true,
];
$doc = $this->mongoCollection->findAndModify($condition, $update, [], $options);
return isset($doc['last']) ? $doc['last'] : false;
}
}
```
示例代碼:
[https://github.com/pinguo/php-msf-demo/app/Tasks/Idallloc.php](https://github.com/pinguo/php-msf-demo/blob/master/app/Tasks/Idallloc.php)
### 調用Task
```php
<?php
/**
* MongoDB操作示例
*
* @author camera360_server@camera360.com
* @copyright Chengdu pinguo Technology Co.,Ltd.
*/
namespace App\Controllers;
use PG\MSF\Controllers\Controller;
use App\Tasks\Idallloc;
class MongoDBTest extends Controller
{
public function actionGetNewId()
{
/**
* @var Idallloc $idAlloc
*/
$idAlloc = $this->getObject(Idallloc::class);
$newId = yield $idAlloc->getNextId('test');
$this->output($newId);
}
}
```
示例代碼:
[https://github.com/pinguo/php-msf-demo/app/Controllers/MongoDBTest.php](https://github.com/pinguo/php-msf-demo/blob/master/app/Controllers/MongoDBTest.php)
我們需要認識到:
1. Worker進程只是將任務投遞給Tasker進程后立即返回,即是非阻塞的投遞;
2. Tasker進程執行相應的業務邏輯,在這里就是從MongoDB獲取新的一個ID;
3. Worker進程是通過協程獲取到Tasker執行結果,即調用需要加yield關鍵字;
### 訪問接口
```bash
[worker@newdev ~]$ curl http://127.0.0.1:8000/MongoDBTest/GetNewId
1
```
- 0 文檔說明
- 1 為什么研發新框架
- 1.1 傳統php-fpm工作模式的問題
- 1.2 壓測數據對比
- 1.3 小結
- 2 微服務框架研發概覽
- 2.1 通信框架技術選型
- 2.2 swoole
- 2.3 協程原理
- 2.4 異步、并發
- 2.5 小結
- 3 框架運行環境
- 3.1 環境變量
- 3.2 運行代碼
- 3.3 docker
- 3.4 小結
- 4 框架結構
- 4.1 結構概述
- 4.2 控制器
- 4.3 模型
- 4.4 視圖
- 4.5 同步任務
- 4.6 配置
- 4.7 路由
- 4.8 小結
- 5 框架組件
- 5.1 協程
- 5.2 類的加載
- 5.3 異步Http Client
- 5.4 請求上下文
- 5.5 連接池
- 5.6 對象池
- 5.7 RPC
- 5.8 公共庫
- 5.9 RESTful
- 5.10 多語言
- 5.11 雜項
- 5.12 小結
- 6 常見問題
- 7 附錄