refactor fsm
This commit is contained in:
parent
b5bf62ded9
commit
2af5fda73e
3 changed files with 42 additions and 38 deletions
|
|
@ -25,40 +25,6 @@ trait Transactor extends Actor {
|
|||
self.makeTransactionRequired
|
||||
}
|
||||
|
||||
trait FsmActor[S] extends Actor {
|
||||
|
||||
type State = scala.PartialFunction[Event, NextState]
|
||||
|
||||
@volatile var currentState: NextState = initialState
|
||||
@volatile var timeoutActor: Option[ActorRef] = None
|
||||
|
||||
def initialState: NextState
|
||||
|
||||
def handleEvent: State = {
|
||||
case event@Event(value,stateData) =>
|
||||
log.warning("No state for event with value %s - keeping current state %s", value, stateData)
|
||||
NextState(currentState.state, stateData, currentState.timeout)
|
||||
}
|
||||
|
||||
protected def receive = {
|
||||
case value => {
|
||||
timeoutActor.foreach{ref => Scheduler.unschedule(ref); timeoutActor = None }
|
||||
|
||||
val event = Event(value, currentState.stateData)
|
||||
currentState = (currentState.state orElse handleEvent).apply(event)
|
||||
|
||||
currentState.timeout.foreach{timeout =>
|
||||
timeoutActor = Some(Scheduler.scheduleOnce(self, StateTimeout, timeout, TimeUnit.MILLISECONDS))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case class NextState(state: State, stateData: S, timeout: Option[Int] = None)
|
||||
case class Event(event: Any, stateData: S)
|
||||
object StateTimeout
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Extend this abstract class to create a remote actor.
|
||||
* <p/>
|
||||
|
|
|
|||
38
akka-core/src/main/scala/actor/Fsm.scala
Normal file
38
akka-core/src/main/scala/actor/Fsm.scala
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
package actor
|
||||
|
||||
import java.util.concurrent.TimeUnit
|
||||
import se.scalablesolutions.akka.actor.{ActorRef, Scheduler, Actor}
|
||||
|
||||
trait Fsm[S] { self: Actor =>
|
||||
|
||||
type State = scala.PartialFunction[Event, NextState]
|
||||
|
||||
@volatile var currentState: NextState = initialState
|
||||
@volatile var timeoutActor: Option[ActorRef] = None
|
||||
|
||||
def initialState: NextState
|
||||
|
||||
def handleEvent: State = {
|
||||
case event@Event(value,stateData) =>
|
||||
log.warning("No state for event with value %s - keeping current state %s", value, stateData)
|
||||
NextState(currentState.state, stateData, currentState.timeout)
|
||||
}
|
||||
|
||||
|
||||
override protected def receive: Receive = {
|
||||
case value => {
|
||||
timeoutActor.foreach{ref => Scheduler.unschedule(ref); timeoutActor = None }
|
||||
|
||||
val event = Event(value, currentState.stateData)
|
||||
currentState = (currentState.state orElse handleEvent).apply(event)
|
||||
|
||||
currentState.timeout.foreach{timeout =>
|
||||
timeoutActor = Some(Scheduler.scheduleOnce(this.self, StateTimeout, timeout, TimeUnit.MILLISECONDS))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case class NextState(state: State, stateData: S, timeout: Option[Int] = None)
|
||||
case class Event(event: Any, stateData: S)
|
||||
}
|
||||
object StateTimeout
|
||||
|
|
@ -7,7 +7,7 @@ package se.scalablesolutions.akka.actor
|
|||
import org.scalatest.junit.JUnitSuite
|
||||
import org.junit.Test
|
||||
import org.multiverse.api.latches.StandardLatch
|
||||
import Actor._
|
||||
import actor.{StateTimeout, Fsm}
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
object FsmActorSpec {
|
||||
|
|
@ -15,7 +15,7 @@ object FsmActorSpec {
|
|||
class Lock(code: String,
|
||||
timeout: Int,
|
||||
unlockedLatch: StandardLatch,
|
||||
lockedLatch: StandardLatch) extends FsmActor[CodeState] {
|
||||
lockedLatch: StandardLatch) extends Actor with Fsm[CodeState] {
|
||||
|
||||
def initialState = NextState(locked, CodeState("", "33221"))
|
||||
|
||||
|
|
@ -26,7 +26,7 @@ object FsmActorSpec {
|
|||
NextState(locked, CodeState(incomplete, code))
|
||||
case codeTry if (codeTry == code) => {
|
||||
doUnlock
|
||||
NextState(open, CodeState("", code), Some(timeout))
|
||||
new NextState(open, CodeState("", code), Some(timeout))
|
||||
}
|
||||
case wrong => {
|
||||
log.error("Wrong code %s", wrong)
|
||||
|
|
@ -66,7 +66,7 @@ class FsmActorSpec extends JUnitSuite {
|
|||
val lockedLatch = new StandardLatch
|
||||
|
||||
// lock that locked after being open for 1 sec
|
||||
val lock = actorOf(new Lock("33221", 1000, unlockedLatch, lockedLatch)).start
|
||||
val lock = Actor.actorOf(new Lock("33221", 1000, unlockedLatch, lockedLatch)).start
|
||||
|
||||
lock ! '3'
|
||||
lock ! '3'
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue