For regular actors, they can be composed. But, I can't seem to find anything about doing it with FSMs. And there isn't a receive block to use += to add things to. Does anyone have any experience trying to generalize an FSM?
I can't provide a code example, because I don't have any code yet because I don't know if I can compose FSMs.
You can compose state behaviour using partial functions in the same way that you compose Actor partial functions. The when()
function requires a partial function of type scala.PartialFunction[FSM.this.Event, FSM.this.State]
). In the example below, I extend the state Jibber
with a partial function (e.g. some common behaviour) declared in the trait. You can use exactly the same technique to extend the onTermination
behaviour from a trait using a PF declared as scala.PartialFunction[StopEvent, Unit]
.
I have lifted significant common behaviour out of some complex FSMs using this technique.
package monster
import akka.actor._
import monster.FlyingSpaghetti._
// State and data objects
object FlyingSpaghetti {
trait State
object Jibber extends State
object Jabber extends State
object Ping
object Done
}
// Trait with common behaviour behaviour
trait FlyingSpaghetti extends Actor with FSM[State,String]{
val layer: StateFunction = {
case Event(Done,s) ⇒
println("Done behaviour layered")
stop()
}
}
class Monster() extends FlyingSpaghetti {
startWith(Jibber,"jabber")
self ! Ping
println("Starting")
// First, do the common behaviour PF then do specialised behaviour
when(Jibber) (layer orElse {
case Event(Ping,"jabber") ⇒
println("jabber")
goto(Jabber) using "jibber"
case Event(Done,s) ⇒
println("Done jabbering")
stop()
})
when(Jabber) {
case Event(Ping,"jibber") ⇒
println("jibber")
goto(Jibber) using "jabber"
case Event(Done,s) ⇒
println("Done jibbering")
stop()
}
}
object Run extends App {
val system = ActorSystem("mySystem")
val rattle = system.actorOf(Props[Monster])
rattle ! Ping
rattle ! Ping
rattle ! Done
Thread.sleep(100)
system.shutdown()
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With