akka.actor.FSM Scala Examples
The following examples show how to use akka.actor.FSM.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example.
Example 1
Source File: FSMAfterAllListenerHolder.scala From reliable-http-client with Apache License 2.0 | 5 votes |
package rhttpc.akkapersistence.impl import akka.actor.FSM import rhttpc.akkapersistence.StateSaved private[akkapersistence] trait FSMAfterAllListenerHolder[S, D] { this: FSM[S, D] => private var currentAfterAllListener: Option[RecipientWithMsg] = None implicit class StateExt(state: this.State) { def acknowledgingAfterSave() = { replyingAfterSave() } def replyingAfterSave(msg: Any = StateSaved) = { currentAfterAllListener = Some(new RecipientWithMsg(sender(), msg)) state } } protected def useCurrentAfterAllListener(): Option[RecipientWithMsg] = { val tmp = currentAfterAllListener currentAfterAllListener = None tmp } }
Example 2
Source File: ReliableFSMSpec.scala From reliable-http-client with Apache License 2.0 | 5 votes |
package rhttpc.akkapersistence import akka.actor.{ActorSystem, FSM, PoisonPill} import akka.persistence._ import akka.testkit._ import org.scalatest._ import rhttpc.akkapersistence.impl._ import rhttpc.client.ReliableClientBaseSpec import scala.concurrent.Await import scala.concurrent.duration._ class ReliableFSMSpec extends TestKit(ActorSystem("ReliableFSMSpec")) with ReliableClientBaseSpec with ImplicitSender with Matchers { it should "save snapshot after message publication and reply with StateSaved" in { fixture => createAndSendFoo(fixture, "12") } it should "recover in correct state not saving snapshot one more time" in { fixture => val id = "123" val actor = createAndSendFoo(fixture, id) val snapshot = actor.underlyingActor.savedSnapshots.head watch(actor) actor ! PoisonPill expectTerminated(actor) val recovered = TestActorRef[FooBarActor](FooBarActor.props(id, fixture.client)) recovered ! NotifyAboutRecoveryCompleted recovered.underlyingActor.recover(snapshot) expectMsg(RecoveryCompleted) Thread.sleep(500) recovered.underlyingActor.savedSnapshots shouldBe empty fixture.transport.replySubscriptionPromise.success("foo") awaitCond(recovered.underlyingActor.savedSnapshots.size == 1) Await.result(fixture.transport.ackOnReplySubscriptionFuture, 3 seconds) recovered ! CurrentState expectMsg(FooState) } def createAndSendFoo(fixture: FixtureParam, id: String): TestActorRef[FooBarActor] = { val actor = TestActorRef[FooBarActor](FooBarActor.props(id, fixture.client)) actor ! SendMsg("foo") Thread.sleep(500) actor.underlyingActor.savedSnapshots shouldBe empty fixture.transport.publicationPromise.success(Unit) awaitCond(actor.underlyingActor.savedSnapshots.size == 1) expectMsg(StateSaved) actor } } trait MockReliableFSM[S, D] extends AbstractReliableFSM[S, D] with MockSnapshotter[S, D] trait MockSnapshotter[S, D] extends AbstractSnapshotter { this: FSM[S, D] => @volatile var savedSnapshots: List[SnapshotWithSeqNr] = List.empty override def saveSnapshotWithSeqNr(snapshot: Any, seqNr: Long): Unit = { savedSnapshots = SnapshotWithSeqNr(snapshot, seqNr) :: savedSnapshots self ! SaveSnapshotSuccess(SnapshotMetadata(persistenceId, seqNr)) } def recover(snap: SnapshotWithSeqNr) = { self ! SnapshotOffer(SnapshotMetadata(persistenceId, snap.seqNr), snap.snapshot) } protected def handleRecover: Receive = { val handleOfferAndThanSendCompleted: Receive = { case offer: SnapshotOffer => receiveRecover(offer) self ! RecoveryCompleted } handleOfferAndThanSendCompleted orElse receiveRecover } whenUnhandled { case Event(event, _) if handleRecover.isDefinedAt(event) => handleRecover(event) stay() } override def deleteSnapshots(criteria: SnapshotSelectionCriteria): Unit = {} } case class SnapshotWithSeqNr(snapshot: Any, seqNr: Long)
Example 3
Source File: TrafficLightFSM.scala From Akka-Cookbook with MIT License | 5 votes |
package com.packt.chapter10 import java.util.Date import akka.actor.{Actor, ActorLogging, ActorRef, FSM} import TrafficLightFSM._ import scala.concurrent.duration._ object TrafficLightFSM { sealed trait TrafficLightState case object Green extends TrafficLightState case object Yellow extends TrafficLightState case object Red extends TrafficLightState sealed trait Data case class Countdown(i: Int) extends Data //Events case object Tick case class ReportChange(to: TrafficLightState, date: Date) } class TrafficLightFSM(changesSubscriber: ActorRef) extends Actor with ActorLogging with FSM[TrafficLightState, Data]{ import context.dispatcher trafficLightState(Green, Yellow, 2) trafficLightState(Yellow, Red, 4) trafficLightState(Red, Green, 8) startWith(Green, Countdown(8)) initialize() scheduleTick() onTransition { case Green -> Yellow => changesSubscriber ! ReportChange(Yellow, new Date()) case Yellow -> Red => changesSubscriber ! ReportChange(Red, new Date()) case Red -> Green => changesSubscriber ! ReportChange(Green, new Date()) } private def scheduleTick() = { context.system.scheduler.scheduleOnce(1 second, self, Tick) } private def trafficLightState( trafficLightState: TrafficLightState, nextTrafficLightState: TrafficLightState, totalSecondsNextState: Int) = { when(trafficLightState) { case Event(Tick, Countdown(i)) if i != 0 => scheduleTick() log.info(s"Current state [$trafficLightState]. Countdown: [$i].") stay using Countdown(i - 1) case Event(Tick, Countdown(i)) if i == 0 => scheduleTick() log.info(s"Changing from $trafficLightState to $nextTrafficLightState.") goto(nextTrafficLightState) using Countdown(totalSecondsNextState) } } }