gpt4 book ai didi

scala - Akka FSM Actor 具有 stash 和 unstashing

转载 作者:行者123 更新时间:2023-12-04 23:39:31 31 4
gpt4 key购买 nike

我想使用 FSM Akka Accor 进行存储/取消存储。我不知道把 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 , Actor 应该改为 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

非常感谢。

最佳答案

您可以通过使用 onTransition 来实现这一点。 FSM上的方法.当状态发生变化时,它会被执行,我们可以利用那个时刻来解开所有消息。至于藏匿,你需要在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()
}
}

如果您还有其他问题,请告诉我 :)

关于scala - Akka FSM Actor 具有 stash 和 unstashing,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42331921/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com