之前写了篇关于call还是cast的讨论,实际等要改成call的时候又发生了疑问。
因为call的确有如下作用:
1. 阻塞客户端
2. 有返回值能确定操作是否成功,并能很好的支持测试
3. 保证时序,只有call成功了,才能继续执行下一步
可是除此之外,还有其他好处吗?麻烦呢?
如果table_server 只是为一个玩家所用,那么可能是合适的。
可惜不是,table_server 还需要广播信息,而这部分广播信息不可能放在玩家进程做,
这样如果在调用端和被调用端都发消息,就有点冗余。
cast 是丢过去不管,有返回自然收到,没有返回的话,对不起你自己看着办重试(看起来更流畅?)
如果call timeout了,call调用的时候,到底该怎么处理?
告诉用户处理失败? 后续收到该处理的操作完成又该怎么告诉用户?
按照GenServer的文档说明,调用者要么崩溃保持干净,
要么就是try catch,并丢弃那些垃圾信息。
胡言乱语,我还是决定应用call,并且广播消息只在桌子进程统一发。
最终还整理了simple_table的测试,以及修正Application.start(GameServer) 为 Application.start(:game_server) 的bug。
暂时到这里了,一整天都在思考call 和cast,以及思考测试的问题,搞得很疲劳。
现在TableServer没什么好测试的,如果像SimpleTable那样去测试,实在显得冗余?
如果不测,又感觉不是很可靠的样子(曾经的elixir项目我是测进程的),也许是第一次采用这种测试分解方法,还不习惯吧。
代码已经发布,后续接着:
添加不翻牌、不补牌的操作加速牌局
添加玩家的操作
以及补充测试
=====================================新的想法=============================
call 大抵适用于那种call期间无需处理其他事情的调用。
像游戏这种,通常中间会有其他消息需要处理,这时候为了及时处理更新,call可能就不合适了。
我想这大概就是大家用cast的最大原因。
引申开来,如果连cast都显得缓慢,那可能又需要直接对socket发操作了(当然这是最后选择)。
我代码就保持call不改了(棋牌可能影响不大),我也懒得改,这个系列主要是探讨总结用的。