美好的一天,
我有一个gen_server进程,它定期执行一些长期运行的状态更新任务
handle_info:
handle_info(trigger, State) ->
NewState = some_long_running_task(),
erlang:send_after(?LOOP_TIME, self(), trigger),
{noreply, NewState}.
Run Code Online (Sandbox Code Playgroud)
但是当这样的任务运行时,整个服务器都没有响应,任何对它的调用都会导致整个服务器崩溃:
my_gen_server:status().
** exception exit: {timeout,{gen_server,call,[my_gen_server,status]}}
in function gen_server:call/2
Run Code Online (Sandbox Code Playgroud)
如何避免阻止gen_server?当一个人my_gen_server:status()随时打电话时,结果应该是这样的:
{ok, task_active}
我是一个真正的Erlang新手(1周前开始),我正在尝试通过创建一个小而有效的聊天服务器来学习这种语言.(当我说效率时,我的意思是我有5台服务器用于对数十万个连接客户端进行压力测试 - 百万将是很棒的!)
我找到了一些教程这样做,唯一的是,我找到的每个教程都是IRC之类的.如果一个用户发送邮件,则除发件人之外的所有用户都将收到邮件.我想稍微改变一下,并使用一对一的讨论.
搜索连接用户的最有效客户端池是什么?我考虑过注册这个过程,因为它似乎做了我需要的一切,但我真的不认为这是更好的方法.(或者最好的方式去做).
有人会有这样的建议吗?
编辑:
每个连接的客户端都会受到ID的影响.
当用户连接时,它首先发送一个登录命令来给它的id.当用户想要将消息发送给另一个消息时,该消息看起来像这样
[ID-NUMBER][Message] %% ID-NUMBER IS A FIXED LENGTH
当我要求"最有效的客户端池"时,我实际上正在寻找在连接的客户端列表上检索/添加/删除一个客户端的最快方法,这可能很大(数十万 - 可能是数百万)
编辑2:
回答一些问题:
我应该使用列表编写自己的搜索客户端功能吗?
或者我应该使用ets?
甚至使用register/2 unregister/1和whereis/1来维护我的客户端列表,使用它的唯一id作为atom,它似乎是最简单的方法,我真的不知道它是否有效,但我我很确定这是丑陋的解决方案;-)?
我正在开发一个项目,我们有一个原子数组作为哈希.每当用户连接到服务器时,都会对某个值进行哈希处理,并将该哈希值用作查找数组中元素的索引,并返回该元素."外部力量"(由长时间运行的gen_server处理)能够更改此数组,因此我不能简单地对其进行硬编码.我的问题是如何"托管"这个数组.
我的第一个实现是一个简单的gen_server,它保存了一个数组的副本并将其发送给任何要求它的人.然后,请求它的过程可以遍历它并获得他们想要的索引.这个实现有大量的内存被使用,我归结为这个相同的数组有很多副本浮动.
我当前的实现有一个中央gen_server来处理这个数组的状态,以及处理实际请求的子节点.当状态改变时,中央gen_server更新子节点.当进程想要找到它的哈希结果时,它会将其索引号发送到中央gen_server,后者将请求转发给其中一个子进程.子进程遍历其"本地"列表,并将生成的原子发送回原始进程.
当前实施的问题在于它在高流量时陷入困境.我已经尝试过越来越多的孩子,但我很确定中央gen_server是瓶颈.
有没有人对我的问题有更好的解决方案?
编辑:%s/array/list/g