Akka支持Actor消息循环处理部分的热切换,调用context.become方法可以使用新的消息循环处理替换当前的消息处理器,被替换的消息处理器被压到一个栈结构,支持消息处理器的出栈和入栈。
注:但Actor重启时,它的消息循环处理恢复到初始的行为。
become方法的参数类型为部分函数PartialFunction[Any, Unit],例如:
1 | import akka.actor.Actor |
2 | import akka.actor.ActorSystem |
3 | import akka.actor.Props |
4 |
5 | class HotSwapActor extends Actor { |
6 | import context. _ |
7 | def angry : Receive = { |
8 | case "foo" = > sender() ! "I am already angry?" |
9 | case "bar" = > become(happy) |
10 | } |
11 | def happy : Receive = { |
12 | case "bar" = > sender() ! "I am already happy :-)" |
13 | case "foo" = > become(angry) |
14 | } |
15 | def receive = { |
16 | case "foo" = > become(angry) |
17 | case "bar" = > become(happy) |
18 | } |
19 | } |
这种become的用法可以用来实现有效状态机(FSM),它总是替换当前的Actor行为,而不是用unbecome(退栈操作)。
另外一种用法,不是替换,而是添加到行为栈的顶部,这种情况需要当心的是,退栈(unbecome)和入栈(become)操作需要匹配,否则会造成内存泄漏。
1 | case object Swap |
2 | class Swapper extends Actor { |
3 | import context. _ |
4 | def receive = { |
5 | case Swap = > |
6 | println( "Hi" ) |
7 | become({ |
8 | case Swap = > |
9 | println( "Ho" ) |
10 | unbecome() // resets the latest ’become’ (just for fun) |
11 | }, discardOld = false ) // push on top instead of replace |
12 | } |
13 | } |
14 | object SwapperApp extends App { |
15 | val system = ActorSystem( "SwapperSystem" ) |
16 | val swap = system.actorOf(Props[Swapper], name = "swapper" ) |
17 | swap ! Swap // print Hi |
18 | swap ! Swap // print Ho |
19 | swap ! Swap // print Hi |
20 | swap ! Swap // print Ho |
21 | swap ! Swap // print Hi |
22 | swap ! Swap // print Ho |
23 | } |