具有存储和取消存储功能的 Akka FSM Actor
Akka FSM Actor with stashing and unstashing
我想 stashing/unstashing 使用 FSM Akka Acctor。我不知道把 stash()
和 unstashAll()
.
放在哪里
我在下面有一个简化的例子:
import akka.actor.{ActorSystem, FSM, Props, Stash}
trait TestState
case object StateA extends TestState
case object StateB extends TestState
case class TestData()
case class MessageA(msg: String)
case class MessageB(msg: String)
case object ChangeState
class TestFSM extends FSM[TestState, TestData] with Stash {
startWith(StateA, TestData())
when(StateA) {
case Event(MessageA(msgA), _) =>
println(s"In StateA: $msgA")
stay()
case Event(ChangeState, _) =>
println("Changing state from A to B")
goto(StateB)
}
when(StateB) {
case Event(MessageB(msgB), _) =>
println(s"In StateB: $msgB")
stay()
}
whenUnhandled {
case Event(e, _) =>
println(s"Unhandled event: $e")
stay()
}
}
object TestFSM extends App {
val system = ActorSystem("test-system")
val actor = system.actorOf(Props[TestFSM])
actor ! MessageA("Apple 1")
actor ! MessageB("Banana 1")
actor ! MessageA("Apple 2")
actor ! ChangeState
actor ! MessageB("Banana 2")
}
初始状态为StateA
。
在 StateA
中,actor 应该只处理 MessageA
类型的消息。如果它收到任何其他类型的消息(ChangeState
除外),它应该将其隐藏起来。收到消息 ChangeState
后,演员应更改为 StateB
。
从 StateA
更改为 StateB
后,它应该取消隐藏所有消息。
在 StateB
中时,actor 应该只处理 MessageB
.
类型的消息
我不确定在哪里使用 stash()
和 unstashAll()
来实现这一点。
我在 运行 上得到的输出是:
In StateA: Apple 1
Unhandled event: MessageB(Banana 1)
In StateA: Apple 2
Changing state from A to B
In StateB: Banana 2
我希望看到的输出是:
In StateA: Apple 1
In StateA: Apple 2
Changing state from A to B
In StateB: Banana 1
In StateB: Banana 2
非常感谢。
您可以通过在 FSM
上使用 onTransition
方法来实现此目的。这会在状态发生变化时执行,我们可以利用那一刻取消隐藏所有消息。至于stashing,需要在whenUnhandled
方法中进行。我还做了一个小更新,这样你就可以在状态之间循环:
class TestFSM extends FSM[TestState, TestData] with Stash {
startWith(StateA, TestData())
when(StateA) {
case Event(MessageA(msgA), _) =>
println(s"In StateA: $msgA")
stay()
case Event(ChangeState, _) =>
println("Changing state from A to B")
goto(StateB)
}
when(StateB) {
case Event(MessageB(msgB), _) =>
println(s"In StateB: $msgB")
stay()
case Event(ChangeState, _) =>
println("Changing state from B to A")
goto(StateA)
}
/**
* Here we can stash all messages. For example when we're in state A,
* we handle both `MessageA` and `ChangeState` messages, but we don't
* handle `MessageB` instances which will end up here. The opposite
* happens when we're in state B.
*/
whenUnhandled {
case _: Event =>
stash()
stay()
}
// When transitioning into another state, unstash all messages.
onTransition {
case StateA -> StateB => unstashAll()
case StateB -> StateA => unstashAll()
}
}
如果您还有其他问题,请告诉我:)
我想 stashing/unstashing 使用 FSM Akka Acctor。我不知道把 stash()
和 unstashAll()
.
我在下面有一个简化的例子:
import akka.actor.{ActorSystem, FSM, Props, Stash}
trait TestState
case object StateA extends TestState
case object StateB extends TestState
case class TestData()
case class MessageA(msg: String)
case class MessageB(msg: String)
case object ChangeState
class TestFSM extends FSM[TestState, TestData] with Stash {
startWith(StateA, TestData())
when(StateA) {
case Event(MessageA(msgA), _) =>
println(s"In StateA: $msgA")
stay()
case Event(ChangeState, _) =>
println("Changing state from A to B")
goto(StateB)
}
when(StateB) {
case Event(MessageB(msgB), _) =>
println(s"In StateB: $msgB")
stay()
}
whenUnhandled {
case Event(e, _) =>
println(s"Unhandled event: $e")
stay()
}
}
object TestFSM extends App {
val system = ActorSystem("test-system")
val actor = system.actorOf(Props[TestFSM])
actor ! MessageA("Apple 1")
actor ! MessageB("Banana 1")
actor ! MessageA("Apple 2")
actor ! ChangeState
actor ! MessageB("Banana 2")
}
初始状态为StateA
。
在 StateA
中,actor 应该只处理 MessageA
类型的消息。如果它收到任何其他类型的消息(ChangeState
除外),它应该将其隐藏起来。收到消息 ChangeState
后,演员应更改为 StateB
。
从 StateA
更改为 StateB
后,它应该取消隐藏所有消息。
在 StateB
中时,actor 应该只处理 MessageB
.
我不确定在哪里使用 stash()
和 unstashAll()
来实现这一点。
我在 运行 上得到的输出是:
In StateA: Apple 1
Unhandled event: MessageB(Banana 1)
In StateA: Apple 2
Changing state from A to B
In StateB: Banana 2
我希望看到的输出是:
In StateA: Apple 1
In StateA: Apple 2
Changing state from A to B
In StateB: Banana 1
In StateB: Banana 2
非常感谢。
您可以通过在 FSM
上使用 onTransition
方法来实现此目的。这会在状态发生变化时执行,我们可以利用那一刻取消隐藏所有消息。至于stashing,需要在whenUnhandled
方法中进行。我还做了一个小更新,这样你就可以在状态之间循环:
class TestFSM extends FSM[TestState, TestData] with Stash {
startWith(StateA, TestData())
when(StateA) {
case Event(MessageA(msgA), _) =>
println(s"In StateA: $msgA")
stay()
case Event(ChangeState, _) =>
println("Changing state from A to B")
goto(StateB)
}
when(StateB) {
case Event(MessageB(msgB), _) =>
println(s"In StateB: $msgB")
stay()
case Event(ChangeState, _) =>
println("Changing state from B to A")
goto(StateA)
}
/**
* Here we can stash all messages. For example when we're in state A,
* we handle both `MessageA` and `ChangeState` messages, but we don't
* handle `MessageB` instances which will end up here. The opposite
* happens when we're in state B.
*/
whenUnhandled {
case _: Event =>
stash()
stay()
}
// When transitioning into another state, unstash all messages.
onTransition {
case StateA -> StateB => unstashAll()
case StateB -> StateA => unstashAll()
}
}
如果您还有其他问题,请告诉我:)