2016-09-02 4 views
1

私はakka FSMパターンを理解しようとしています。次の例では、なぜ処理が完了したのか理解できません。私の印刷物は、私が完成したことを明確に示しています。誰かが私を啓発してくれますか?このFSMの例の動作を説明するには?

import akka.actor.{ActorRef, FSM} 
import scala.concurrent.duration._ 
import akka.actor.Actor 
import akka.actor.ActorSystem 
import akka.actor.FSM.Event 
import akka.actor.Props 

object FSM2 extends App{ 
    val system = ActorSystem("test") 
    val test = system.actorOf(Props[Test], "t") 
    test ! Set("hello") 
} 

sealed trait State 
case object idle extends State 
case object processing extends State 
case object complete extends State 

sealed trait Data 
case class Content(processing:Int) extends Data 

class Test extends FSM[State, Data]{ 

    when(idle) { 
    case Event(test:Set[String], _) => { 
     goto(processing) using Content(test.size-1) 
    } 
} 
    when(processing, stateTimeout = 1 second) { 
    case Event(StateTimeout, Content(count)) => { 
    println(count) 
    count match { 
     case 0 => goto(complete) using Content(0) 
     case _ => stay using Content(count) 
    } 
    } 
    } 
    when (complete, stateTimeout = 1 second) { 
    case Event(StateTimeout, _) => { 
     println("in complete") 
     goto(idle) using Content(0) 
    } 
} 

    onTransition({ 
    case idle -> processing => { 
    println("idle -> processing") 
    } 
    case processing -> complete => { 
     println("processing -> complete") 
    } 
    }) 

    startWith(idle, Content(0)) 
    initialize() 
} 
output: 
idle -> processing 
idle -> processing 
0 
idle -> processing 
in complete 
idle -> processing 

I thought this would be the expected output: 

idle -> processing 
0 
idle -> processing 
processing -> complete 
in complete 
(go back to idle with no print) 

私が書いた他のコードでは、パターンマッチングは行われず、代わりに割り当てが行われることが示唆されています。

Stateオブジェクト(アイドル、処理、完了、アイドル→処理など)で大文字の文字を使用すると機能します。

答えて

3

主な問題は、case idle -> processingがあなたのケースのオブジェクトではなく、何かに一致し、それらのanythingsを名前idleprocessingにバインドすることです。これらのケースオブジェクトにマッチさせるには、安定した識別子をマッチさせる必要があります。これは、ケースオブジェクトを大文字で開始するか(すでに観察したように)、マッチでバッククックで囲むことです。

これを念頭に置いて、文字列"idle -> processing"は、アイドル状態から処理する状態だけでなく、すべての状態遷移に対して出力され、println(s"$idle -> $processing")を印刷することで確認できます。

output: 
idle -> processing // triggered by initialize(), is actually idle -> idle 
idle -> processing // the actual idle -> processing transition 
0 
idle -> processing // processing -> complete 
in complete 
idle -> processing // complete -> idle 
+0

は、他の説明に言及いただきありがとうございます:) – stian

+0

ます。また、大文字にケースオブジェクトの名前を変更することにより、この問題を解決することができますなどの「処理」、「アイドル」、この方法でコンパイラはそれらに一致しようとします。 –

関連する問題