Hello!
2015-05-18 19:43 GMT+08:00 贾凯:
> 通过阅读代码,我看到Lua默认使用调用栈记录coroutine的调用关系,而openresty添加了使用树来记录调用
> 关系,我认为的原因有:1.为了支持actor异步非阻塞模型;2.为了实现可自己调度的thread;不知我理解的
> 对不对?请问是否还有其他原因?
理解是对的。
对于 1: 因为任何 I/O 操作或者 sleep 操作都会 yield,而 Lua coroutine 只能 yield 一级,而在
ngx_lua 的上下文中需要直接 yield 到顶层,从而把控制权交还给 nginx 事件循环,所以我们必须重新自己实现一遍 Lua 的
coroutine API.
对于 2,更是显然的了,毕竟是和标准的 coroutine API 很不相同的语义和行为。
> 但是openresty还保留了默认的基于栈管理的方式,但只是在没有__ngx_req变量的情况下使用。为什么不统一为一个实现呢?我认为Lua默认的方式完全用不到了。。。
默认的 coroutine API 实现只在 init_by_lua 的上下文中有意义。另外一个有意义的场景是基于 Lua debug
hook 的外部 Lua 调试器。所以 OpenResty 对特殊的场景保留了标准的 coroutine 实现。
> 没有__ngx_req变量的场景我知道的有init_by_lua下,还有其他的吗?
>
好像没有了。不过很快 init_by_lua 也会有 __ngx_req 了,因为我希望 init_by_lua 上下文也能支持
cosocket API 等等高级功能。当然,和 init_worker_by_lua 以及 ngx.timer.at 上下文类似,这里的
__ngx_req 指向伪造的请求对象。
Regards,
-agentzh