最近工作压力有点大,情绪偶然会失控,要好好反省一下自己。

上周本来打算写CSP相关的东西,但是目前做得还不够多,积累的经验不足,就放弃了。中间找到很好的参考资料,一并放在这里。一篇是比较短的论文,可以观其大略:http://www.cs.ucf.edu/courses/cop4020/sum2009/CSP-hoare.pdf,另一个链接是hoare写的关于进程演算的书:https://dl.dropboxusercontent.com/u/5660734/CSPbook_2004_Hoare.rar 对于理解CSP这个模型的数学基础很有帮助。不过书好长,还没看完。。。

本周合并了另一个项目组对mongodb改造的修改,对方完全重写我的代码,但没有配套单元测试,合并当天就测出bug了,有点碎碎念啊。没办法,硬着头皮剥离一部分依赖,独立出一个可执行文件来测bson_format的问题。正如之前写的这篇博客提到的,难点在于类型系统的对接。本次修改增加了一个array迭代,保证初次在引擎这边分配array的时候,已经是一块足够长的内存,而不是我原来实现时,迭代bson,有一个元素就合并一个。另外,上次序列化为bson时,我错将array当mapping来序列化了,原有的测试只针对长度,没针对具体内容,本次修改已经修正。

另外一个地方,是关于内存对象的生命周期的。本次修改直接重写了dbo_new, dbo_load, dbo_unload等方法,这些方法控制了dbd内存中,存放在apr_list里的一系列db对象。gamed通过rpc调用,以dbo_new或者dbo_load方法创建对象后,除非调用dbo_unload,否则对象是不会被释放的,整个生命周期非常清晰。虽然dbd启动过程中初始化了vm虚拟机,实际上并没有跑lpc脚本,所有工作都是在c层实现的。本次修改中,在序列化过程里,用到的字符串局部变量,都是通过vm虚拟机来申请和释放的。个人对此持保留看法。在序列化过程中,所用到的key值都是临时性的,bson化后就没有意义。一个简单粗暴的做法,就是直接在函数内定义定长字符串数组,然后每次需要序列化bson key的时候,都复制/格式化到这个数组上。这一方面可以避免堆区内存分配,另一方面避免无谓的内存泄露,以及可能出现的二次释放问题。

稍后,通过单元测试,修正了当天测试暴露出来的,反序列化array嵌套mapping对象时,array元素没有初始化好,导致序列化嵌套mapping时,引擎core dump的问题。接着,对方又抛出了一个新的修改,依然是没有单元测试。。目标是修正引擎的概率性崩溃,依据是序列化mapping过程中,对key做字符串化操作时,会改动到原有的mapping,然后造成内存泄露和/或mapping元素的二次释放问题,引致引擎崩溃。经单元测试发现,这个理由不成立,但代码里的确会有误释放的问题。至于误释放为什么没有引起单元测试崩溃,这个还需要看看gc那一块的代码。这次bug fix就没有吸合了,稍后通过在函数内定义一个局部定长字符串数组,加上key的复制来解决吧。

通过这几次引擎的修改,越来越发现,没有单元测试的代码,真的会没有信心的。不是说你用这个代码跑了两周,没有发现存储有问题,这个代码就是没有问题的。不同项目组里,用到的储存结构不一样,也许你的代码嵌套3层以后就会崩掉呢?或者就是这次暴露出的,复合类型的嵌套储存bug呢?没有办法用单元测试重现的bug,只靠看代码猜测,我觉得是不靠谱的,因为修好后你也没办法重现bug的环境,看看本次修改是否有效。希望大伙能够早日认同这个道理

做完底层又要赶逻辑代码,差点回不了家,残念……

dbd到mongo的序列化问题及稳定性的更多相关文章

  1. Java Mongo 自定义序列化笔记

    从insert方法入手 1. org.springframework.data.mongodb.repository.support.SimpleMongoRepository.java   inse ...

  2. 【mongo】mongo数据转json时特殊类型处理

    mongo数据库中的有些数据类型是无法用json序列化的,比如ObjectId或者datetime.datetime类型. 可以通过json.JSONEncoder来处理 import json im ...

  3. [java]序列化框架性能对比(kryo、hessian、java、protostuff)

    序列化框架性能对比(kryo.hessian.java.protostuff) 简介:   优点 缺点 Kryo 速度快,序列化后体积小 跨语言支持较复杂 Hessian 默认支持跨语言 较慢 Pro ...

  4. 序列化框架性能对比(kryo、hessian、java、protostuff)

    简介:   优点 缺点 Kryo 速度快,序列化后体积小 跨语言支持较复杂 Hessian 默认支持跨语言 较慢 Protostuff 速度快,基于protobuf 需静态编译 Protostuff- ...

  5. 转:使用Mongo Connector和Elasticsearch实现模糊匹配

    原文来自于:http://www.csdn.net/article/2014-09-01/2821485-how-to-perform-fuzzy-matching-with-mongo-connec ...

  6. 谈谈序列化—实体bean一定要实现Serializable接口?

    导读:最近在做项目的过程中,发现一个问题,就是我们最开始的时候,传递参数包括返回类型,都有map类型.但是由于map每次都要匹配key值,很麻烦.所以在之后就将参数传递和返回类型全都改成了实体bean ...

  7. Mongo C# Driver 聚合使用---深入浅出

    聚合查询结构体系 ​ 我们都知道Mongo中聚合是由$match,$project等聚合项组成,所以在C# Driver中具有两种类型:聚合管道(PipelineDefinition)和聚合管道项(I ...

  8. 迄今为止 .Net 平台功能最强大,性能最佳的 JSON 序列化和反序列化库。

    Swifter.Json 这是迄今为止 .Net 平台功能最强大,性能最佳的 JSON 序列化和反序列化库. Github : https://github.com/Dogwei/Swifter.Js ...

  9. 对Java Serializable(序列化)的理解和总结(一)

    导读:最近在做项目的过程中,发现一个问题,就是我们最开始的时候,传递参数包括返回类型,都有map类型.但是由于map每次都要匹配key值,很麻烦.所以在之后就将参数传递和返回类型全都改成了实体bean ...

随机推荐

  1. javascript 判断身份证的正确性

    function isIdCardNo(vals) { var cardNum = vals; if (cardNum.length == 0) { return true; } // 11-15,2 ...

  2. 用Navicat for MYsql创建表,插入中文显乱码

    段都有编码设置.出现乱码肯定是你现在用的编码混乱造成的 解决办法: 第一步 先改数据库编码 先修改你的数据库,如果你页面用的是UTF-8编码那么你数据库内的编码也需要设置为UTF-8,每个字段都需要设 ...

  3. POJ 1083 Moving Tables 思路 难度:0

    http://poj.org/problem?id=1083 这道题题意是有若干段线段,每次要求线段不重叠地取,问最少取多少次. 因为这些线段都是必须取的,所以需要让空隙最小 思路: 循环直到线段全部 ...

  4. subString用法,字符串保持一定位数,不足补0

    Substrinig(a,b): 从下标a开始截取,共截取b位 实现:一串数字,中间两位数字+2,生成新的一串数字 "; , number.Length - );//前8位 );//后6位 ...

  5. ROS主题发布订阅控制真实的机器人下位机

    先模拟控制小乌龟 新建cmd_node.ccpp文件: #include"ros/ros.h" #include"geometry_msgs/Twist.h" ...

  6. 创建ROS功能包(四)

    为了方便直接用ROS的create-pkg命令行工具 roscreate-pkg chapter2_tutorials std_msgs rospy roscpp std_msgs 包含了常见的消息类 ...

  7. DrawerLayout一个简单的实例(与ActionBar无关)

    官方的Demo里有DrawerLayout的例子,涉及到ActionBar,这里不用ActionBar,手痒,写个超级简单的小Demo,备着以后或许会用到. 详细的内容,可以访问:http://blo ...

  8. C++-模板的声明和实现为何要放在头文件中

    源: http://blog.csdn.net/lqk1985/archive/2008/10/24/3136364.aspx 如何组织编写模板程序 发表日期: 1/21/2003 12:28:58 ...

  9. Linux-Gcc生成和使用静态库和动态库详解

    一.基本概念 1.1什么是库 在windows平台和linux平台下都大量存在着库. 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行. 由于windows和linux的平台不同( ...

  10. [rfc3261]sip - via header

    在很多情况下,sip并非直达目标主机的,而是要经过很多中间节点服务器.在request消息中,via头域表示当前已走过的节点(每经过一个节点,添加一个via头):在response消息中,via头域表 ...