我有一个状态机,我想使用scalaz-stream Process1进行建模。
状态机模拟客户端和服务器之间的消息流。
一组基本数据类型可能是:
sealed trait ServerState
case object Disconnected extends ServerState
case object Authenticating extends ServerState
case object Idle extends ServerState
case object Busy extends ServerState
sealed trait Message
case object Query extends Message
case object StartupMessage extends Message
case object AuthenticationOk extends Message
case object QueryResponse extends Message
在我的脑海中,这将由Process1[I, O]
建模,其中type I = Message
和type O = scalaz.State[Message, ServerState]
。
它就像是迷雾 - 我可以看到解决方案的轮廓,但它的坚定定义让我感到惊讶。
目前我有一些看起来像这样的东西
type Transition = scalaz.State[Message, ServerState]
val connecting = Transition { StartupMessage => (StartupMessage, Authenticating) }
def fsm(state: Transition): Process1[Message, Transition] = {
Await [Message, Transition] { msg =>
case (connecting, AuthenticationOk) => Emit1(connecting)
}
}
我知道这是错的,但我无法弄清楚州过渡需要居住的地方。
当Message
驱动程序处理内部状态时,进程是否应接受ServerState
并返回物理Process1
?
我很难看到如何随身携带"此时无法执行的消息。
示例:
1. Current ServerState = Disconnected
2. StateMachine gets Query Message
3. StateMachine must send StartupMessage, ServerState now equals = Authenticating
4. StateMachine receives AuthenticationOk, ServerState now equals Idle
5. StateMachine must now sends original query message, ServerState now equals Busy
6. StateMachine gets QueryResponse, ServerState now equals Idle
答案 0 :(得分:3)
我认为您应该能够通过这样的递归Process1[Message, Message]
对状态机进行编码
def fsm(state: ServerState): Process1[Message, Message] = {
receive1 { msg: Message =>
(msg, state) match {
case (Query, Disconnected) =>
emit(StartupMessage) fby fsm(Authenticating)
case (AuthenticationOk, Authenticating) =>
fsm(Idle)
...
}
}
}
您可能希望通过设置{{1来区分机器接受的Message
作为事件(触发转换)和它发出的事件(作为"动作") }}