使用ExActor的Elixir有一种根据条件进行休眠的方法

时间:2016-01-16 15:19:38

标签: elixir

我目前正在学习Elixir开发拍卖网站。因此,每次拍卖都有一名工人,当工人开始工作时,它可能会立即进入休眠状态,但在拍卖结束前的最后N分钟,我不希望每次收到投标时我的工作人员都要休眠(告诉我,如果我错了,但可能效率不高)。

我已经开始使用基本的GenServer OTP(handle_call,handle_info ...)进行开发,我正在使用ExActor和Fsm(均来自SašaJurić)进行重构,并尝试应用CQRS / ES。

有没有办法使用ExActor实现这一点,而不是回到handle_call“basics”?

我想实现类似的目标:

{:reply, ...}在拍卖结束前不到10分钟。

{:reply, ..., :hibernate}当拍卖结束时还有超过10分钟。

1 个答案:

答案 0 :(得分:2)

在Erlang中,休眠会做以下事情:

  • 丢弃进程调用堆栈
  • 做垃圾收集
  • 之后,进程内存可能会减少到低于最小堆大小的值
  • 进程唤醒消息(如果邮箱中有消息,则立即唤醒)
  • 在醒来时,还有另一个垃圾收集,恢复正常的流程大小

休眠和唤醒是CPU密集型的,可以节省很少的内存。我的建议是要么根本不使用它,要么进行一些性能测试,看看它是否值得。如果你有数百万的拍卖流程并且他们很少收到新的消息,那么可能会有一些内存增加,但不要指望任何大的。

您可以根据条件轻松切换休眠。在普通的OTP中写这样的东西就足够了:

case time_left > ten_minutes do
  true -> {:reply, new_state, :hibernate}
  false -> {:reply, new_state}
end

在ExActor中它将是:

defcall your_funcion(args), state: state, do
  ...
  case time_left > ten_minutes do
    true -> set_and_reply(new_state, :hibernate)
    false -> set_and_reply(new_state, timeout)
  end
end

reply这样的宏采用可选参数,即超时值或:hibernate原子。

PS。 您可能对real time bidding in Erlang的文章感兴趣。