Closed twose closed 3 weeks ago
Co::shutdown 命名好坑,建议
中断,有用,支持。
Co::shutdown 命名好坑,建议
- Co::kill
采纳
能不能提供更多中断的使用场景?
@qxhy123 能不能提供更多中断的使用场景?
这个问题很适合在这里解答
在现有方案中, 异步安全重启+平滑退出都是有最大超时时间的, 如果服务长时间没有顺利完成手头已有任务, 进程会被直接强制退出, 可能会造成一些未知的问题. 但是有协程中断功能后, 可以在超时后先尝试取消所有协程, 所有IO会按照失败分支逻辑运行, 完成使命(如服务器能够正确地返回超时错误, 当前服务不可用等), 而不是由于进程挂掉而导致请求丢失/连接被强制切断
如题, 原先已挂起的协程是不可主动调度的
框架层一定会非常需要这样层次的API来进行控制
和传统PHP的类似功能的API不同的是, swoole中大量的API增加了timeout参数, 当然也有部分难以添加或者说不合适添加timeout参数的(会很奇怪, 设计上也有困难), 比如文件操作系列函数, 现在一切都有了可能, 我们可以在PHP层实现任意IO操作的超时, 而无需依赖于底层的API设计
延伸这个特性, 我们甚至可以期望用PHP代码实现强大的Debug工具, 如进入一个挂起的协程进行一些DEBUG调试, 然后再将它挂起
中断,有用,支持。
支持
支持
支持
支持
有用,可以更好管理协程
有用
支持 非常重要的功能
哇,超时熔断,期待!!!
支持支持,,,,我看已经有个pr了
非常需要
非常需要
支持支持 需要此功能
i do
赞
关于 Co::cancel
所表达的仅 sleep , 对于其它IO协程 会发生什么
Co::cancel(go(function () {
$result = file_get_contents('...'); // 这里会发生什么
}))
需不需要退出功能呢?
@twose
function Co::exit() {
Co::kill(Co::getCid());
}
function do_something() {
static $i = 0;
$i++;
echo $i;
if ($i == 5) {
Co::exit();
}
}
go(function () {
while(true) {
do_something();
Co::sleep(1);
}
});
// 输出 12345
支持
您的邮件已收到!
您的邮件已收到!
协程中断
Co::cancel
)Co::throw
)Co::kill
)需要了解的概念
以上三个功能都是基于协程中断特性的, 只有处于
cancelable
(可取消)的操作中的协程才能被取消/置异常/杀死
, 当你成功中断一个协程时, 上下文环境将会立即切换到对应协程中尝试
取消/置异常/杀死
一个处于不可取消操作中的协程, 将会返回false, 此时调用swoole_last_error()
返回值为SWOOLE_ERROR_CO_NONCANCELABLE_OPERATION
尝试
取消/置异常/杀死
一个不存在的协程, 将会返回false, 此时调用swoole_last_error()
返回值为SWOOLE_ERROR_CO_NOT_EXIST
尝试
置异常
一个协程成功后, 协程内抛出的异常的错误码$e->getCode
值为SWOOLE_ERROR_CO_INTERRUPTED_BY_EXCEPTION
, 并且异常将可以通过$e->getOriginCid()
,$e->getOriginFile()
,$e->getOriginFile()
,$e->getOriginTrace()
来获取是哪个协程的哪个位置将当前协程置异常的例子
取消操作:
如果sleep操作被取消, 将返回
剩余未sleep的秒数, 为float型
, 可以通过Co::isCancelled
来判断当前操作是否是被手动取消的, 如sleep操作正常结束, 将返回true
, 如失败, 将返回false
指定协程抛出异常
将会输出异常对象, 此操作和在Co::yield()之后马上抛出异常等价, 但是这个异常会额外包含来源的信息
杀死协程
不会有任何输出
更多相关示例代码及测试请见: https://github.com/swoole/swoole-src/tree/interrupt/tests/swoole_coroutine/interrupt
协程中抛出异常未捕获将不再会导致进程退出
协程中产生普通的未捕获异常(Exception)不再会导致进程退出, 而是导致协程退出, 并产生一条协程异常退出的错误日志, 如:
产生致命错误时(Error)进程将无法继续正常运行, 仍会导致进程退出