March 15, 2015

抵抗组织:阿瓦隆及兰斯洛特扩充

昨天下午约了一帮同事去密室,由于在最后 40 秒成功破关,大家都很兴奋,决定再换个地方欢乐一下,结果就在地图上找了家附近的桌游店。

一开始有 8 个人, 我知道这么多人想开桌游实在没有什么好的选择。玩了两局赛马后又来了三个人。一开始,我实在不想再玩 bluffing game 了。无论是狼人或三国杀,还是抵抗组织,都在三年前玩伤了(开桌游店的日子里,长达半年的时间,每周两个晚上抵抗组织)。

这时发现桌游店里有一盒阿瓦隆。一直听说抵抗组织出了这么一个扩充并且口碑非常的好(bgg 上 party game 分类第一),所以饶有兴趣的读了一下规则书。的确有那么一点意思,就组织大家开了几局。正好 11 个人,我可以做主持人。(当然抵抗组织和杀人狼人不同,玩熟了后,完全不需要额外的主持人的)

阅读全文 "抵抗组织:阿瓦隆及兰斯洛特扩充" »

March 13, 2015

给 sproto 增加 unordered map 的支持

花了两天给 sproto 增加了 unordered map 的支持。

问题是这样的:

sproto 支持数组,但很多情况下,业务处理中,我们并不用数组来保存大量的相同类型的结构数据。因为那样不方便检索。

比如你要配置若干地图表、NPC 表等等的信息,固然可以用 sproto 的 array 来保存。但是在运行时,你更希望用定义好的 id 来检索它们。如果 sproto 不支持 unordered map 的话,你就需要在 decode 之后,对 array table 做一次遍历,用一张新表来建立索引。

google protocal buffers 2 也有这个问题,据说第 3 版要增加 map 用来兼容 json ,这个话题最后再说。

阅读全文 "给 sproto 增加 unordered map 的支持" »

March 11, 2015

跳出死循环

在 skynet 中,有一个叫 monitor 的内部模块,它会监测是否有服务可能陷入了死循环。

工作原理是这样的:每次处理一个服务的一个消息时,都会在一个和服务相关的全局变量处自增 1 。而 monitor 是一个独立线程,它每隔一小段时间(5 秒左右)都检测一下所有的工作线程,看有没有长期没有自增的,若有就认为其正在处理的消息可能陷入死循环了。

而发现这种异常情况后,skynet 能做的也仅仅是输出一行 log 。它无法从外部中断消息处理过程,而死循环的服务,将永久占据一个核心,让系统整体性能下降。

采用 skynet 的 kill 指令是无法杀掉死循环的服务的。


当服务用 lua 编写时,我们则有可能做多一点工作。

阅读全文 "跳出死循环" »

February 28, 2015

skynet 1.0 发布计划

按原定计划,在 lua 5.3 正式发布后, skynet 也将发布 1.0 版了。这样,可以方便维护一个稳定的版本,让使用它的同学们更放心。

目前,github 仓库的主分支已经切换到 lua53 ,也就是将内置版本升级到 lua 5.3 后的分支。未来的 1.0 版也将基于这个分支开发(打上 1.0 的 tag 后,会合并回 master 分支)。

基本特性方面,2014 年 11 月 0.9 版之后,skynet 就没有什么变化过。我们公司内部也有 2 个项目长期线上运行,没有发现明显的问题。

虽然近期还在开发一些新特性。但都是可以完全和旧特性独立开的,也就是说,如果你不使用新特性,就不会引入新特性可能引入的新 bug 。

阅读全文 "skynet 1.0 发布计划" »

February 11, 2015

在线调试 Lua 代码

一直有人问,如果调试 skynet 构件的服务。

我的简单答案是,仔细 review 代码,加 log 输出。长一点的答案是,尽量熟悉 skynet 的构造,充分利用预留的监控接口,自己编写工具辅助调试。

之前的好多年,我也写过很多 lua 的调试器,这里就不一一翻旧帖了。今天要说的是,我最终还是计划加入 1.0 正式版的调试控制台。

也就是单步跟踪调试单个 lua coroutine 的能力。这对许多新手来说是个学走路的拐杖,虽然有人一辈子都扔不掉。

阅读全文 "在线调试 Lua 代码" »

February 10, 2015

怎样在运行时插入运行一段 Lua 代码

最近想给 skynet 加一个在线调试器,方便调试 Lua 编写的服务。

Lua 本身没有提供现成的调试器,但有功能完备的 debug api 。通常、我们可以在代码中插入 debug.debug() 就可以进入一个交互环境,输入任何 Lua 指令。当然,你也可以在 debug hook 里调用它。

但这种交互方式有一个缺点:lua 直接用 load 翻译输入的文本,转译为一个 lua 函数并运行。这注定了这个输入的代码中不能直接访问到上下文的局部变量和 upvalue 。

如果想读写上下文中的局部变量或 upvalue ,还得使用 debug.getlocal 等函数。这无疑是相当麻烦的。

阅读全文 "怎样在运行时插入运行一段 Lua 代码" »

January 30, 2015

Lua 5.3 升级注意

最近在慢慢把公司的几个项目从 Lua 5.2 迁移到 Lua 5.3 ,为发布 skynet 1.0 alpha 版做准备。

在更新代码时发现了一些注意点,罗列一下:

Lua 5.3 去掉了关于 unsigned 等的 api ,现在全部用 lua_Integer 类型了。这些只需要换掉 api ,加上强制转换即可。通常不会有什么问题。

最需要细致 review 代码升级的是和序列化相关的库。在 skynet 里是序列化库、sproto、bson 等。我们还用到了 protobuffer ,也和序列化有关。

这是因为,Lua 5.3 提供了整型支持,而序列化工作通常需要区分浮点和整数分开处理。json 这种文本方式则不需要,同样还有 redis 的通讯协议也是如此。

过去判断一个 number 是浮点还是整数,需要用 lua_tonumberlua_tointeger 各取一份做比较。虽然到了 Lua 5.3 这种代码理论上可以不用改动,但正确的方法应该是使用 lua_isinteger

阅读全文 "Lua 5.3 升级注意" »

Misc

Categories

Archives

Recent Comments