Skip to content

Commit b5c4748

Browse files
authored
Update README.md
1 parent b0eb54f commit b5c4748

File tree

1 file changed

+24
-68
lines changed

1 file changed

+24
-68
lines changed

README.md

Lines changed: 24 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -79,46 +79,16 @@ go(function () {
7979

8080
## 接口
8181
所有模式的Task在执行时所处的协程与原协程不是同一个,所以**所有基于[Context](https://wiki.swoole.com/wiki/page/865.html)的变量传递与维护会失效**,务必注意这一点。
82-
### 模式1:伪异步模式
83-
```php
84-
\Swlib\Archer::task(callable $task_callback, ?array $params = null, ?callable $finish_callback = null): int;
85-
```
86-
- `$task_callback` 待执行的函数,
87-
- `$params` 传入`$task_callback`中的参数,可缺省
88-
- `$finish_callback` Task执行完之后的回调,可缺省,格式如下:
89-
90-
```php
91-
function (int $task_id, $task_return_value, ?\Throwable $e) {
92-
// $task_id 为\Swlib\Archer::task() 返回的Task id
93-
// $task_return_value 为Task闭包 $task_callback 的返回值,若没有返回值或抛出了异常,则该项为null
94-
// $e为Task闭包 $task_callback 中抛出的异常,正常情况下为null
95-
}
96-
```
97-
| 返回模式 | 协程说明 | 异常处理 |
98-
| :-- | :-- | :-- |
99-
| 返回 Taskid | $task_callback与$finish_callback处于同一个协程,但与当前协程不处于同一个 | 通过第3个参数传递给$finish_callback,若缺省则会产生一个warning |
100-
### 模式2:协程同步返回模式
101-
(该模式与直接执行协程代码的区别在于:会进入Task队列,受队列的size和最大并发影响;运行于不同的协程)
102-
```php
103-
\Swlib\Archer::taskWait(callable $task_callback, ?array $params = null, ?float $timeout = null): mixed;
104-
```
105-
- `$task_callback` 待执行的函数,
106-
- `$params` 传入`$task_callback`中的参数,可缺省
107-
- `$timeout` 超时时间,超时后函数会直接抛出`Swlib\Archer\Exception\TaskTimeoutException`。注意:超时返回后Task仍会继续执行,不会中断,不会移出队列。若缺省则表示不会超时
108-
109-
| 返回模式 | 协程说明 | 异常处理 |
110-
| :-- | :-- | :-- |
111-
| 当前协程挂起,直到Task执行完成并返回结果 | $task_callback与当前协程不是同一个 | 若Task抛出了任何异常,Archer会捕获后在这里抛出。 |
112-
### 模式3:Defer模式
82+
### 模式1:Defer模式 (即CSP模型)
11383
获取Task:
11484
```php
11585
/*定义*/ \Swlib\Archer::taskDefer(callable $task_callback, ?array $params = null): \Swlib\Archer\Task\Defer;
11686
$task = \Swlib\Archer::taskDefer($task_callback, ['foo', 'bar']);
11787
```
11888

119-
| 返回模式 | 协程说明 | 异常处理 |
120-
| :-- | :-- | :-- |
121-
| 返回Task对象 | $task_callback与当前协程不是同一个 | 若Task抛出了任何异常,Archer会捕获后在执行recv时抛出。 |
89+
| 返回模式 | 异常处理 |
90+
| :-- | :-- |
91+
| 返回Task对象 | 若Task抛出了任何异常,Archer会捕获后在执行recv时抛出。 |
12292

12393
获取执行结果:
12494
```php
@@ -127,10 +97,10 @@ $task->recv(0.5);
12797
```
12898
- `$timeout` 超时时间,超时后函数会直接抛出`Swlib\Archer\Exception\TaskTimeoutException`。注意:超时返回后Task仍会继续执行,不会中断,不会移出队列。若缺省则表示不会超时
12999

130-
| 返回模式 | 协程说明 | 异常处理 |
131-
| :-- | :-- | :-- |
132-
| 若Task已执行完则直接返回结果。否则协程挂起,等待执行完毕后恢复并返回结果。 | $task_callback与当前协程不是同一个 | 若Task抛出了任何异常,Archer会捕获后会在此处抛出。 |
133-
### 模式4:Task集模式
100+
| 返回模式 | 异常处理 |
101+
| :-- | :-- |
102+
| 若Task已执行完则直接返回结果。否则协程挂起,等待执行完毕后恢复并返回结果。 | 若Task抛出了任何异常,Archer会捕获后会在此处抛出。 |
103+
### 模式2:Task集模式
134104
获取容器:
135105
```php
136106
// $max_concurrent表示集内最大并行数量,缺省表示不限制
@@ -147,9 +117,9 @@ $container->waitForAll(?float $timeout = null): array;
147117
```
148118
- `$timeout` 超时时间,超时后函数会直接抛出`Swlib\Archer\Exception\TaskTimeoutException`。注意:超时返回后所有Task仍会继续执行,不会中断,不会移出队列。若缺省则表示不会超时
149119

150-
| 返回模式 | 协程说明 | 异常处理 |
151-
| :-- | :-- | :-- |
152-
| 若运行时所有Task已执行完,则会直接以键值对的形式返回所有Task的返回值。否则当前协程挂起。当所有Task执行完成后,会恢复投递的协程,并返回结果。 | 所有Task所处协程均不同 | 若某个Task抛出了任何异常,不会影响其他Task的执行,但在返回值中不会出现该Task id对应的项,需要通过`getError(int $taskid)``getErrorMap()`方法获取异常对象 |
120+
| 返回模式 | 异常处理 |
121+
| :-- | :-- |
122+
| 若运行时所有Task已执行完,则会直接以键值对的形式返回所有Task的返回值。否则当前协程挂起。当所有Task执行完成后,会恢复投递的协程,并返回结果。 | 若某个Task抛出了任何异常,不会影响其他Task的执行,但在返回值中不会出现该Task id对应的项,需要通过`getError(int $taskid)``getErrorMap()`方法获取异常对象 |
153123
###### 先完成先返回:各Task的执行结果会根据其完成的顺序,以键值对的形式yield出来
154124
对于生成器(Generator)的定义:[查看](http://php.net/manual/zh/class.generator.php)
155125
```php
@@ -158,9 +128,9 @@ $container->yieldEachOne(?float $timeout = null): \Generator;
158128
- `$timeout` 超时时间,超时后函数会直接抛出`Swlib\Archer\Exception\TaskTimeoutException`(该时间表示花费在本方法内的时间,外界调用该方法处理每个返回值所耗费的时间不计入)。注意:超时返回后所有Task仍会继续执行,不会中断,不会移出队列。若缺省则表示不会超时
159129
- 生成器遍历完成后,可以通过 `Generator->getReturn()` 方法获取返回值的键值对
160130

161-
| 返回模式 | 协程说明 | 异常处理 |
162-
| :-- | :-- | :-- |
163-
| 若运行时已经有些Task已执行完,则会按执行完毕的顺序将他们先yield出来。若这之后仍存在未执行完的Task,则当前协程将会挂起,每有一个Task执行完,当前协程将恢复且其结果就会以以键值对的方式yield出来,然后协程会挂起等待下一个执行完的Task。 | 所有Task所处协程均不同 | 若某个Task抛出了任何异常,不会影响其他Task的执行,但这个Task不会被`yield`出来,需要通过`getError(int $taskid)``getErrorMap()`方法获取异常对象 |
131+
| 返回模式 | 异常处理 |
132+
| :-- | :-- |
133+
| 若运行时已经有些Task已执行完,则会按执行完毕的顺序将他们先yield出来。若这之后仍存在未执行完的Task,则当前协程将会挂起,每有一个Task执行完,当前协程将恢复且其结果就会以以键值对的方式yield出来,然后协程会挂起等待下一个执行完的Task。 | 若某个Task抛出了任何异常,不会影响其他Task的执行,但这个Task不会被`yield`出来,需要通过`getError(int $taskid)``getErrorMap()`方法获取异常对象 |
164134

165135
获取某Task抛出的异常(若Task未抛出异常则返回null)
166136
```php
@@ -170,24 +140,24 @@ $container->getError(int $id): ?\Throwable;
170140
```php
171141
$container->getErrorMap(): array;
172142
```
173-
### 模式5:一次性计时器模式
143+
### 模式3:一次性计时器模式
174144
该模式的Task不受[队列配置](https://github.com/swlib/archer#%E9%85%8D%E7%BD%AE)的影响
175145
(该模式与直接使用co::sleep()执行协程代码的区别在于:不直接切换走当前协程;底层经过算法优化,会减少并行sleep()的协程数量,节约内存;可以在执行之前清除掉计时器;运行于不同的协程)
176146
```php
177147
\Swlib\Archer::taskTimerAfter(float $after_time, callable $task_callback, ?array $params = null): int;
178148
```
179149
- `$after_time` 计时时间,单位为秒
180150

181-
| 返回模式 | 协程说明 | 异常处理 |
182-
| :-- | :-- | :-- |
183-
| 返回 Taskid | $task_callback与当前协程不是同一个 | Archer会捕获异常,并产生一个warning |
151+
| 返回模式 | 异常处理 |
152+
| :-- | :-- |
153+
| 返回 Taskid | Archer会捕获异常,并产生一个warning |
184154

185155
取消执行:
186156
```php
187157
$taskid = \Swlib\Archer::taskTimerAfter(1.5, function() { echo 'aaa'; });
188158
\Swlib\Archer::clearTimerTask($taskid); // 返回true为成功,若已执行则返回false
189159
```
190-
### 模式6:持续型计时器模式
160+
### 模式4:持续型计时器模式
191161
该模式的Task不受[队列配置](https://github.com/swlib/archer#%E9%85%8D%E7%BD%AE)的影响
192162
(该模式与直接使用co::sleep()执行协程代码的区别在于:不直接切换走当前协程;底层经过算法优化,会减少并行sleep()的协程数量,节约内存;可以在执行之前清除掉计时器;运行于不同的协程)
193163
```php
@@ -196,9 +166,9 @@ $taskid = \Swlib\Archer::taskTimerAfter(1.5, function() { echo 'aaa'; });
196166
- `$tick_time` 执行间隔,单位为秒
197167
- `$first_time_after` 初次执行计时器,单位为秒。若缺省则与`$tick_time`相同
198168

199-
| 返回模式 | 协程说明 | 异常处理 |
200-
| :-- | :-- | :-- |
201-
| 返回 Taskid | $task_callback与当前协程不是同一个 | Archer会捕获异常,并产生一个warning |
169+
| 返回模式 | 异常处理 |
170+
| :-- | :-- |
171+
| 返回 Taskid | Archer会捕获异常,并产生一个warning |
202172

203173
取消执行:
204174
```php
@@ -254,20 +224,6 @@ Archer会抛出以下几种异常:
254224

255225
## 例子
256226
###### *假设所有场景均已处于协程环境之中;场景都是理想化,简易化的;除了例子中使用的闭包,Archer支持所有[callable类型](http://php.net/manual/zh/language.types.callable.php)
257-
#### 场景:记录用户操作时间,但并不关心执行结果,也不想等待SQL执行完
258-
```php
259-
\Swlib\Archer::task(function(int $user_id, int $timestamp): void {
260-
$swoole_mysql = new Swoole\Coroutine\MySQL();
261-
$swoole_mysql->connect([
262-
'host' => '127.0.0.1',
263-
'port' => 3306,
264-
'user' => 'user',
265-
'password' => 'pass',
266-
'database' => 'test',
267-
]);
268-
$swoole_mysql->prepare('UPDATE `user` SET `optime`=? WHERE `id`=?')->execute([$timestamp, $user_id], 10);
269-
}, [1, time()]);
270-
```
271227
#### 场景:执行某些协程Client(或由[Runtime::enableCoroutine()](https://wiki.swoole.com/wiki/page/965.html)变为协程的传统Client)时,未开启或无法开启[Defer特性](https://wiki.swoole.com/wiki/page/p-coroutine_multi_call.html),但又想使用Defer功能。
272228
```php
273229
$task_redis = \Swlib\Archer::taskDefer(function() {
@@ -314,7 +270,7 @@ $task_callback = function(int $id): int {
314270
$map = [];
315271
$map2 = [];
316272
$results = [];
317-
for ($id=1; $id<=20; ++$id) {// 我知道这个可以用 GROUP BY 一条SQL实现,这里只是举个例子
273+
for ($id=1; $id<=20; ++$id) {// 虽然用 GROUP BY 一条SQL实现,这里只是举个例子
318274
$taskid = $container->addTask($task_callback, [$id]);
319275
$map[$taskid] = $id;
320276
$map2[$id] = $taskid;
@@ -351,7 +307,7 @@ for ($id=1; $id<=20; ++$id) {
351307
}
352308

353309
foreach ($container->yieldEachOne(10) as $taskid=>$count) {
354-
$server->send($map[$taskid], $count); // 不要纠结为什么 fd 和 id 取值一样,这只是一个简化的场景例子,正式应用肯定更复杂
310+
$server->send($map[$taskid], $count); // 假设 fd 和 id 取值一样,这只是一个简化的场景例子,正式应用肯定更复杂
355311
unset($map[$taskid]);
356312
}
357313

0 commit comments

Comments
 (0)