免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3374 | 回复: 5
打印 上一主题 下一主题

[其他] [lua相关] 一些宿主嵌入lua设计方面的问题, 一定要理解我的意思再解答! [复制链接]

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-03-14 11:56 |只看该作者 |倒序浏览
本帖最后由 linux_c_py_php 于 2013-03-14 12:04 编辑

   这两天动手去做了一下嵌入lua的server(包括提供connect, read_util, write等lua api).

   写完之后, 我突然意识到了实现上几个致命的硬伤, 希望得到指点.

   先说说我的设计:

   1, server采用select做事件循环.
   2, server调用accept后, 为该connection创建一个lua_State, 创建一个userdata设置为global var, 以便后续暴露给lua使用.
   3, server采用状态机维护连接状态, 其状态转移为:
   
  
before_request(过渡状态, 用于注册read event) -> wait_request -> before_response(过渡状态, 用于取消read event, 注册write event) -> wait_response(创建一个lua coroutine并启动, 定时轮询检测coroutine生死, 死后取消write event重新进入before_request)

   
   在wait_request阶段解析到request, 则经过before_response设置write event后进入wait_response阶段.  

   在wait_response阶段, 第一次调用时会从该连接的lua_State创建一个coroutine并resume.

   在此之后, 由于处于wait_request阶段并且注册了write event, 所以server框架会一直触发此连接的回调,
   进入状态机的wait_request状态来lua_status()查看coroutine是否死亡, 一旦判定为死亡, 则说明本次lua执行结束,
   则会清理掉这个coroutine, 通过进入before_request -> wait_request继续进入下一轮请求解析.

   
   就这样的设计, 通过给lua执行时间加上timeout检测, cpu通常也不会因为write event的轮询而异常繁忙, 并且一切也能正常的工作.

  
这样设计, 应该是因为我受lighttpd/nginx的插件架构影响较深的原因.




   但写完后, 我就觉得有几个地方我自己都觉得不爽:

   ①, 因为我提供了connect/read_util/write等lua api, 如果是我此种设计, 想做到长连接connect会很不自然很没结构, 因为我的coroutine不是常驻的.

   所以我意识到一个常驻的coroutine设计多么重要:
   1, accept后就为该连接启动一个coroutine, 在lua层面的代码变成了while get_req() end的循环取请求结构(可以让用户仅填callback, while我们替其隐藏在api里).
   2, 在server端要做的就是当解析到req后, 根据lua层的api:get_req 是否已经yield(在yield前标记变量以便server层进行判定)决定是否有必要resume该coroutine.
   
   ②, 我之所以要一个connection创建一个lua_State, 想来唯一的原因就是想给每个coroutine暴露一个独立的全局变量, 为了这个目的创建那么多lua_State很破费.
        
      
能不能推荐一个官方一点的做法, 能够整个server只用一个lua_State, 并且能够保证在lua代码层面可以直接使用一个全局变量, 比如叫做: core, 而不需要做其他多余的操作.

        
        我能想到的方法可能是:
       1, 一个全局lua_State.
       2, 在accept连接后, 为其创建一个table存储连接相关信息, 再创建一个userdata: core, 然后把core存在前面的table中.
       3, load一份lua代码, 设置它的第1个环境(5.1里用lua_setenv, 5.2里是setupvalue第1个upvalue(_ENV)) 为前面那个table, 这样coroutine就会有不同的环境表了.
       4, 创建一个常驻coroutine , 把这个coroutine记录在前面的table里(为了保持一个引用计数, 也为了可以在C层获取其lua_State), 然后coroutine reumse跑起.
       5, 把table存在以fd为下标的全局索引table中.

       这样之后, server可以从lua_State的全局索引table根据fd取到table, 拿出其中的userdata, 也可以拿出里面的coroutine的lua_State, 可以用来resume.
       另外, 想清理一个fd对应的lua数据, 只要从全局索引table中清理掉该fd的数据即可, 因为可以一下子把userdata和coroutine的引用减少为0 , 可以垃圾回收了.

      
      


论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
2 [报告]
发表于 2013-03-14 12:05 |只看该作者

论坛徽章:
27
处女座
日期:2016-04-18 14:00:4515-16赛季CBA联赛之福建
日期:2023-03-31 15:54:2315-16赛季CBA联赛之深圳
日期:2020-06-02 10:10:5015-16赛季CBA联赛之广夏
日期:2019-07-23 16:59:452016科比退役纪念章
日期:2019-06-26 16:59:1315-16赛季CBA联赛之天津
日期:2019-05-28 14:25:1915-16赛季CBA联赛之青岛
日期:2019-05-16 10:14:082016科比退役纪念章
日期:2019-01-11 14:44:062016科比退役纪念章
日期:2018-07-18 16:17:4015-16赛季CBA联赛之上海
日期:2017-08-22 18:18:5515-16赛季CBA联赛之江苏
日期:2017-08-04 17:00:4715-16赛季CBA联赛之佛山
日期:2017-02-20 18:21:13
3 [报告]
发表于 2013-03-14 16:10 |只看该作者
用LUA来处理连接 没尝试过 貌似也只有云风那样的牛人才喜欢这样干

论坛徽章:
27
处女座
日期:2016-04-18 14:00:4515-16赛季CBA联赛之福建
日期:2023-03-31 15:54:2315-16赛季CBA联赛之深圳
日期:2020-06-02 10:10:5015-16赛季CBA联赛之广夏
日期:2019-07-23 16:59:452016科比退役纪念章
日期:2019-06-26 16:59:1315-16赛季CBA联赛之天津
日期:2019-05-28 14:25:1915-16赛季CBA联赛之青岛
日期:2019-05-16 10:14:082016科比退役纪念章
日期:2019-01-11 14:44:062016科比退役纪念章
日期:2018-07-18 16:17:4015-16赛季CBA联赛之上海
日期:2017-08-22 18:18:5515-16赛季CBA联赛之江苏
日期:2017-08-04 17:00:4715-16赛季CBA联赛之佛山
日期:2017-02-20 18:21:13
4 [报告]
发表于 2013-03-14 16:11 |只看该作者
你为什么不参考下他的skynet呢?

http://blog.codingnow.com/2012/09/the_design_of_skynet.html

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
5 [报告]
发表于 2013-03-14 17:35 |只看该作者
可以参考一下.

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
6 [报告]
发表于 2013-03-14 18:50 |只看该作者
以前做个类似的事情,实现有些不同。
用C写个web server,然后用 cgilua 让第三方定制特殊的 http 请求。
C和lua各自做擅长的领域。

撸主的做法,属于娱乐性软件玩法,实际未必有很好的效果。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP