Hello!
2012/8/16 pengqi <fen...@gmail.com>:
> coroutine.status()现在用的就是原始的定义,所以反应的也就是原始的状态。所以实际上只有main
> coroutine有normal状态,之前和晓哲老师也讨论过这个问题,当时觉得这种情况暂时可以接受,就没有去实现一个自定义的版本(之前也没有想到一个简单的自定义实现,lua和luajit的status检查实现貌似还不太一样)。
>
这里的一个设计目标是让 Lua 程序员感觉不到差别,呵呵,所以 coroutine.status() 最终还是要和标准 API
的文档保持一致 :) Lua 5.1 和 LuaJIT 2.0 在 coroutine.status()
的实现上确实有区别,我们还是应当避免在 ngx_lua 中重复它的实现。
> 要不我们自己为每个coroutine维护一个status(取值就为4种状态),然后根据lua状态的规则在coroutine各个自定义接口以及run_thread函数里面coroutine自然结束时根据情况改变相关coroutine的status?
>
目前看来,这是唯一做法了,即我们自己追踪 coroutine 的当前状态,就像我们目前自己追踪 coroutine
的逻辑父亲一样。我目前的想法是把目前的 ngx_http_lua_ctx_t 实例拆分开为许多个 ngx_http_lua_co_ctx_t
实例,每一个 Lua coroutine 都对应一个自己的 ngx_http_lua_co_ctx_t 实例。然后在这个 ctx
结构中记录当前 coroutine 的状态,还有当前 coroutine 的逻辑父亲(这样那个存在 registry 中的 parents
表也可以省了)。
由于在 ngx.thread API 的实现中,我们无论如何都是需要拆分 ngx_http_lua_ctx_t 为每个 thread
对应一个 ctx 结构,所以不如提早引入此机制而把 coroutine.status() 的问题给解决了?
由于这里的讨论越来越有趣了,相信其他人也会对这里的实现细节感兴趣,所以我同时抄送给了 openresty 邮件列表 :)
Best regards,
-agentzh
>
> 在 2012年8月17日 下午12:50,agentzh <age...@gmail.com>写道:
>
>> 同志们!
>>
>> 由于目前 ngx_lua coroutine API 采取了扁平化的实现,所有的 coroutine resume 都是在顶层的 main
>> thread 上进行的,于是在任一 coroutine 运行时,其所有逻辑上的父 coroutine
>> 的状态都不是期望中的"normal",是"suspended". 这至少会导致两个问题:
>>
>> 1. coroutine.status() 函数返回的值失准,与标准 Lua 和 LuaJIT 中的行为不一致,
>> 2. 无法检测用户 coroutine 之间的间接无限递归 resume,会直接导致 lua panic,而标准 Lua
>> 会立即返回“cannot resume normal coroutine”的错误信息。
>>
>> 如何有效解决这两个问题?有什么想法?
>>
>> Best regards,
>> -agentzh