简单Elixir游戏服设计-关于call还是cast

之前写了篇关于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不改了(棋牌可能影响不大),我也懒得改,这个系列主要是探讨总结用的。

原文地址:https://www.cnblogs.com/rubyist/p/7680323.html