https://github.com/celluloid/celluloid/wiki/Protocol-Interaction
注意:这一部分为高阶内容,使用上较复杂。建议不要轻易尝试。
Celluloid 使用的异步消息协议可以让你直接为 actors 添加某些行为。
想要发送一个原始的异步消息(raw asynchronous message)给 actor,使用Celluloid::Mailbox#<
- actor.mailbox << MyMessage.new
- class MyActor
- include Celluloid
- def initialize
- async.wait_for_my_messages
- end
- def wait_for_my_messages
- loop do
- message = receive { |msg| msg.is_a? MyMessage }
- puts "Got a MyMessage: #{message.inspect}"
- end
- end
- end
#receive 一被调用即进入睡眠状态,直到接收到符合条件(block 进行判断)的消息。
在 actor 外部使用 #receive 方法基本起不了什么作用。要小心设置 #recevie ,将其放倒发送消息的事务之前,否则你可能会丢失一些 message。
customized actor behaviors:未来可能会实现客户化actor 定制行为。
二、Finite State Machines:有限状态机
https://github.com/celluloid/celluloid/wiki/Finite-State-Machines
Celluloid 描述有限状态机有很多种模式。
1、内建的 FSM 模块:
Celluloid::FSM 是模仿 Erlang语言中的 gen_fsm。功能相对来说较少(某种角度看未尝不是好事),这个模块直接集成在 Celluloid 功能集中,比如 Timer(超时后状态转移)。
Celluloid::FSM 相关文档
示例程序:
- class Connection
- default_state :connected
- state :connected, :to => :disconnected do
- puts "Connected!"
- end
- state :disconnected
- end
2、第三方的 RubyGems
stately gem
state_machine gem
statemachine gem
三、Finalizers使用 finalizer 类方法可以在 actor 退出时设置一个回调函数,进行收尾工作:
- class Foo
- include Celluloid
- finalizer :my_finalizer
- def my_finalizer
- ...
- end
- end
如果在 finalizer 中调用了其他 actor ,必须采用异步方式。同步调用可能无法返回到正确的 actor 上下文中,因为当前的 actor 很可能已经执行完毕终止了,其 mailbox 也失效了。
- class Foo
- include Celluloid
- finalizer :my_finalizer
- def my_finalizer
- Actor[:server].some_method # 代码不好, 可能会崩溃
- Actor[:server].async.some_method # 很好,可以正常工作
- end
- end
使用 Celluloid.kill(actor)时 finalizer 不会被调用。
当前只允许一个 finalizer ,未来版本的 Celluloid 可能允许多个 finalizer。
已废弃功能:
旧版本的 Celluloid 允许你简单的通过 def finalizer 定义 finalizer 。新版本不行,要通过以上方式,调用类方法 finalizer 来定义。