锁定老帖子 主题:如何把erlang应用在项目中?
该帖已经被评为良好帖
|
|
---|---|
作者 | 正文 |
发表时间:2007-07-28
iunknown 写道 我遇到的情况也类似。最常见的情况是长函数一大堆,或者因为模块划分不好,导致循环依赖。在这个坛子里,大多数人都认为 c++ 难学难精,但是在我遇到的情况中,好像是反过来,反而好像认为随便一个人都是 c++ 高手,有些重要的关于项目方面的决策也没怎么讨论,随便就交给了一个新手,结果就像 qiezi 说的:“很多C++项目,明显是生手的练习,各种漏洞一大堆”。
长函数是普遍情况了,呵呵。比较合理的情况,公用库放在外面,项目特定的代码应该只有少于1/5的代码用来把一些库串联起来,而逻辑部分则应该占到1/2或更多,其它都是完成架构不可少的胶合代码。但目前一些项目,几十个文件在一起,只有几个文件是逻辑的,但却不能离开其它文件单独拿来测试。逻辑处理基本上都是长函数,加上没有很好的利用分级日志,排错非常麻烦,服务器又不能经常重启去做调试。 iunknown 写道 呵呵,公司有那么宽松的时间给你? 口水ing 。。。。。。 我经常也有这样的想法,不过公司基本上不会答应。所以只好自己业余时间来试了。 我刚到这公司时,写代码就是有名的快,一周的任务都是一天之内完成,其实也不是很快,只不过大家都习惯了慢。搞C++的多半都喜欢调试而不喜欢单元测试,我正是使用这一简单的敏捷方式来提高开发效率,可测试的代码通常接口也比较好,重用性也会很好。初期大家都不放心,不过负责的几个项目都是最稳定的,也就没什么疑虑了。这样我每周可以省很多时间,几乎所有的时间都是在写代码或看书。对我来说时间还是充裕的,只不过喜欢的东西太杂太多,每样都搞点皮毛,所以显得也很忙。通常服务器系统写完测试上线还需要监控一段时间,这段时间基本上是不分配任务的,定时上去监控看一下日志就好,一般这些时间有些同事在聊天、下棋什么的(好像公司不反对),我拿这些时间看书或写代码。多点练习也是好的,我刚来时公司有很多各方面的专家,很短一段时间以后,我就发现他们的很多理论是错误的,很多都是在做项目的过程中看过一些文档后就深信不疑,而我喜欢写代码验证,所以一段时间以后我的意见就能成为更有参考价值的。 又跑题了。难怪说:3页之内必跑题,如果没跑肯定是前2页已经跑了。。 跑题也没什么,话题都是扩展的,如果能把一个帖子的各个回帖打标签就好了,连在一起看时也可以知道是怎么跑到这个话题上的,分开看也价值。 |
|
返回顶楼 | |
发表时间:2007-07-28
引用 长函数是普遍情况了,呵呵。比较合理的情况,公用库放在外面,项目特定的代码应该只有少于1/5的代码用来把一些库串联起来,而逻辑部分则应该占到1/2 或更多,其它都是完成架构不可少的胶合代码。但目前一些项目,几十个文件在一起,只有几个文件是逻辑的,但却不能离开其它文件单独拿来测试。逻辑处理基本上都是长函数,加上没有很好的利用分级日志,排错非常麻烦,服务器又不能经常重启去做调试。
出现长函数,或者模块划分不清楚,很多时候是由于开发人员没有清晰的分层意识,没有分清楚公用库和胶合代码。有时候有些库是从特定项目中重构出来的。在重构成库的过程中,没有考虑清楚这个库的主体功能,从而把一些胶合代码也被放到了库里面。导致这个库本身就依赖于太多的其他库。当需要使用这个库的时候,令人发狂的事情就开始了。 引用 我刚到这公司时,写代码就是有名的快,一周的任务都是一天之内完成,其实也不是很快,只不过大家都习惯了慢。搞C++的多半都喜欢调试而不喜欢单元测试,我正是使用这一简单的敏捷方式来提高开发效率,可测试的代码通常接口也比较好,重用性也会很好。
嗯,对于后台开发,很多复杂的情况,不用单元测试,可能还没那么容易模拟出来。单元测试一般来说,能够比较方便地模拟出自己想要的前提条件。 另外,你们公司还是比较人性化啊,做得快,剩下的时间可以自己支配。最担心就是公司见你做得快,很好,再来一个!然后你变成了做得最快,但是最忙的人,呵呵。 |
|
返回顶楼 | |
发表时间:2007-07-31
iunknown 写道 另外,你们公司还是比较人性化啊,做得快,剩下的时间可以自己支配。最担心就是公司见你做得快,很好,再来一个!然后你变成了做得最快,但是最忙的人,呵呵。 我们公司是给自己做软件,作为WEB应用,稳定性比进度重要。通常逻辑也比较简单,只是要从系统架构上考虑任何一个点挂掉以后的备用策略。 ---------------------------------------------------------------------------- 这个帖子提到的erlang应用,我简单测试了一下还是可行的,简单总结一下用到的知识。 1、分布式结点发送消息注册服务: {manager, 'a@xxx.xxx.xxx.xxx'} ! {reg_service, auth, self()} 2、监测节点退出: monitor_node('a@xxx.xxx.xxx.xxx', true) 然后接收: {nodedown, Node} 3、监测进程退出: process_flag(trap_exit, true), link(Pid) 4、远程节点心跳检测: erl -heart 设置心跳间隔: erl -heart -env HEART_BEAT_TIMEOUT 30 设置30秒心跳间隔,范围是10-65535秒之间。 有这些应该够用了。如果是C程序,如何发出monitor_node和process_flag/link呢?也可以从erlang节点上检测C节点,不过还是想知道反过来怎么检测。 |
|
返回顶楼 | |
发表时间:2007-07-31
节点间的通讯协议见otp_src_R11B-5\erts\emulator\internal_doc\erl_ext_dist.txt
erl_interface 目前还不支持 link monitor的op, 只能send receive 数据。 理论上自己可以扩展ei 自己来解释这几条op |
|
返回顶楼 | |
发表时间:2007-07-31
mryufeng 写道 节点间的通讯协议见otp_src_R11B-5\erts\emulator\internal_doc\erl_ext_dist.txt
erl_interface 目前还不支持 link monitor的op, 只能send receive 数据。 理论上自己可以扩展ei 自己来解释这几条op 原来如此。看到这些协议了: 引用 4.2.1.1 LINK {1, FromPid, ToPid} 4.2.1.3 EXIT {3, FromPid, ToPid, Reason} 4.2.1.4 UNLINK {4, FromPid, ToPid} 引用 4.4.1 MONITOR_P {19, FromPid, ToProc, Ref} FromPid = monitoring process ToProc = monitored process pid or name (atom) 4.4.2 DEMONITOR_P {20, FromPid, ToProc, Ref} We include the FromPid just in case we want to trace this. FromPid = monitoring process ToProc = monitored process pid or name (atom) 4.4.3 MONITOR_P_EXIT {21, FromProc, ToPid, Ref, Reason} FromProc = monitored process pid or name (atom) ToPid = monitoring process Reason = exit reason for the monitored process 看样子都是基于Process的,难道monitor_node实际上是用link或monitor_p协议做出来的?不过我看erts/emulator/beam/dist.c里面有个monitor_node_3,但没有以public方式开放出来。 |
|
返回顶楼 | |
发表时间:2007-07-31
monitor是 erts\emulator\beam\erl_monitors.c 里面实现的 看下 .h的说明
/********************************************************************** * Header for monitors and links data structures. * Monitors are kept in an AVL tree and the data structures for * the four different types of monitors are like this: ********************************************************************** * Local monitor by pid/port: * (Ref is always same in all involved data structures) ********************************************************************** * Process/Port X Process Y * +-------------+ +-------------+ * Type: | MON_ORIGIN | | MON_TARGET | * +-------------+ +-------------+ * Pid: | Pid(Y) | | Pid/Port(X) | * +-------------+ +-------------+ * Name: | [] | | [] | * +-------------+ +-------------+ ********************************************************************** * Local monitor by name: (Ref is always same in all involved data structures) ********************************************************************** * Process X Process Y (name foo) * +-------------+ +-------------+ * Type: | MON_ORIGIN | | MON_TARGET | * +-------------+ +-------------+ * Pid: | Pid(Y) | | Pid(X) | * +-------------+ +-------------+ * Name: | Atom(foo) | | Atom(foo) | * +-------------+ +-------------+ ********************************************************************** * Remote monitor by pid: (Ref is always same in all involved data structures) ********************************************************************** * Node A | Node B * ---------------------------------+---------------------------------- * Process X (@A) Distentry @A Distentry @B Process Y (@B) * for node B for node A * +-------------+ +-------------+ +-------------+ +-------------+ * Type: | MON_ORIGIN | | MON_TARGET | | MON_ORIGIN | | MON_TARGET | * +-------------+ +-------------+ +-------------+ +-------------+ * Pid: | Pid(Y) | | Pid(X) | | Pid(Y) | | Pid(X) | * +-------------+ +-------------+ +-------------+ +-------------+ * Name: | [] | | [] | | [] | | [] | * +-------------+ +-------------+ +-------------+ +-------------+ ********************************************************************** * Remote monitor by name: (Ref is always same in all involved data structures) ********************************************************************** * Node A | Node B * ---------------------------------+---------------------------------- * Process X (@A) Distentry @A Distentry @B Process Y (@B) * for node B for node A (name foo) * +-------------+ +-------------+ +-------------+ +-------------+ * Type: | MON_ORIGIN | | MON_TARGET | | MON_ORIGIN | | MON_TARGET | * +-------------+ +-------------+ +-------------+ +-------------+ * Pid: | Atom(node B)| | Pid(X) | | Pid(Y) | | Pid(X) | * +-------------+ +-------------+ +-------------+ +-------------+ * Name: | Atom(foo) | | Atom(foo) | | Atom(foo) | | Atom(foo) | * +-------------+ +-------------+ +-------------+ +-------------+ * The reason for the node atom in X->pid is that we don't know the actual * pid of the monitored process on the other node when setting the monitor * (which is done asyncronously). **********************************************************************/ |
|
返回顶楼 | |
发表时间:2007-07-31
erl的trace更是强大 erts\emulator\beam\erl_trace.c emulator的实现 还有更cool的 et_viewer 对整个message 的流向更是 尽收眼底, 对分布程序的调试真是太方便了
|
|
返回顶楼 | |