3

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]私の頭では、これは a 、 where 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返す必要がありますか?ServerStateProcess1

現時点では実行できないメッセージを「運ぶ」方法を見つけるのに苦労しています。

例:

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
4

1 に答える 1

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)
      ...
    }
  }
}

マシンがMessage(遷移をトリガーするために) イベントとして受け入れる と (「アクション」として) マシンが発行するものを、Process1[InMessage, OutMessage]

于 2015-03-05T06:38:49.280 に答える