Akka recommend pratice to init `PersistentActor` - scala

case class State(id: Long, remain: Int) {
def take(t: Take) = copy(remain = remain - t.amount)
}
object StateService {
def getInitState(id: Long): Future[State]
}
sealed trait Evt
case class Init(id: Long) extends Evt
case class Take(id: Long, amount: Int) extends Evt
class FooActor extends PersistentActor {
var state: State
def receiveCommand = {
case Init(id) => ??? // how to
case t: Take => persistAsync(t) {case e => state = state.take(t)}
}
}
object FooActor {
}
As example described
How could I init the actor state before accepting any other commands ?

You can use different behaviors:
case class State(id: Long, remain: Int)
object StateService {
def getInitState(id: Long): Future[State]
}
sealed trait Evt
case class Init(id: Long) extends Evt
class FooActor extends PersistentActor {
var state: State
import akka.pattern.pipe
def notInitialized: Receive = {
case Init(id) =>
// for simplicity, failure is not handled
StateService.getInitState(id) pipeTo self
case st: State =>
state = st
context become initialized
}
def initialized: Receive = {
case _ => // meh
}
def receiveCommand = notInitialized
}
object FooActor {
}
You can even remove the mutable state altogether by passing it as parameters to the initialized behavior (e.g. initialized(state)).
And regarding the recovery, from official Akka docs:
It's also possible to switch between different command handlers during
normal processing and recovery with context.become() and
context.unbecome(). To get the actor into the same state after
recovery you need to take special care to perform the same state
transitions with become and unbecome in the receiveRecover method as
you would have done in the command handler. Note that when using
become from receiveRecover it will still only use the receiveRecover
behavior when replaying the events. When replay is completed it will
use the new behavior.

Related

Inject different factories to the same actor

I'm new to Akka and Guice, and just started to explore it.
I'm trying to make a father actor, that produce child actors from one specific type, to be more generic- so it'll produce many kind of child actors with different types.
Currently- I inject to the father-actor a Factory of one specific type of actor,
I don't want to add more cases to the father actor, I'd like to solve this problem in more elegant way.
so now I have 2 child actors, and I want to Inject their factory to the father-actor, to do so i thought that maybe I should create the father-actor twice, and each time to inject a different type of Factory.
what I would want to achieve is something like this code
(this code is not working, but this is the idea):
Base Factory trait:
trait BaseFactory {
apply(id: Int) : Actor
}
object FirstActor {
trait Factory extends BaseFactory
}
class FirstActor (#Assisted id: Int) extends Actor with InjectedActorSupport {
....
}
object SecondActor {
trait Factory extends BaseFactory
}
class SecondActor (#Assisted id: Int) extends Actor with InjectedActorSupport {
....
}
class Father #Inject()(factory: BaseFactory, name: String) extends Actor with InjectedActorSupport {
override def receive: Receive = {
case Command =>
...
val actor = context.child(id)
.getOrElse(injectedChild(factory(id), name, _.withMailbox("deque-mailbox")))
}
}
And then the module:
(this part is not compiling since I can't pass the Factories to props as a trait definition and not an instance)
class Module extends AkkaGuiceSupport {
def configure(): Unit = {
bindActor[ExecutorsOffice]("FirstFather", Props(new Father(FirstActor.Factory)))
bindActor[ExecutorsOffice]("SecondFather", Props(new Father(SecondActor.Factory)))
bindActorFactory[FirstActor, FirstActor.Factory]
bindActorFactory[SecondActor, SecondActor.Factory]
}
I'll be happy to hear your thoughts, and your solutions (other solutions will be great also!)
I'm not sure why you'd need Guice-injection.
type PropsCreator = String => Props
object ParentActor {
def props(childPropsCreator: PropsCreator) = Props(classOf[ParentActor], childPropsCreator)
}
class ParentActor(childPropsCreator: PropsCreator) extends Actor {
// yadda yadda yadda
def receive(): Receive = {
case x: Command =>
// yadda yadda yadda
val child = context.child(id)
.getOrElse(context.actorOf(childPropsCreator(id), id))
child.forward(x)
}
}
object DdvRenderProcessManager {
def props(id: String) = Props(classOf[DdvRenderProcessManager], id)
}
class DdvRenderProcessManager(id: String) extends Actor {
// definition omitted
}
object UpdateProcessManager {
def props(id: String) = Props(classOf[UpdateProcessManager], id)
}
class UpdateProcessManager(id: String) extends Actor {
// definition omitted
}
Then you'd create parents like
val ddvRenderParent = system.actorOf(ParentActor.props(DdvRenderProcessManager.props _), "ddvRenderParent")
val updateParent = system.actorOf(ParentActor.props(UpdateProcessManager.props _), "updateParent")
If you wanted to, for instance have all the DdvRenderProcessManagers have a certain dynamic value:
object DdvRenderProcessManager {
// could also express as
// def props(x: Int)(id: String): Props
// and curry, but this expression is clearer about intent
def propsFor(x: Int): String => Props = { (id: String) =>
Props(classOf[DdvRenderProcessManager], id, x)
}
}
class DdvRenderProcessManager(id: String, x: Int) extends Actor {
// definition omitted
}
And then
val ddvRenderParent = system.actorOf(ParentActor.props(DdvRenderProcessManager.propsFor(42)), "ddvRenderParent")
You could even make the dynamic value implicit to allow for something very-close to compile-time DI.

Usage of state in updateState method (Persistent Actor)

From Akka Cookbook, example from chapter Persistent Actors. In SamplePersistentActor.scala there is line of code that I don't quite understand. Here's the full code of 2 files.
SamplePersistentActor.scala:
class SamplePersistenceActor extends PersistentActor {
override val persistenceId = "unique-id-1"
var state = ActiveUsers()
def updateState(event:Event) = state = state.update(event)
val receiveRecover: Receive = {
case evt: Event => updateState(evt)
case SnapshotOffer(_, snapshot: ActiveUsers) => state = snapshot
}
override val receiveCommand: Receive = {
case UserUpdate(userId, Add) =>
persist(AddUserEvent(userId))(updateState)
case UserUpdate(userId, Remove) =>
persist(RemoveUserEvent(userId))(updateState)
case "snap" => saveSnapshot(state)
case "print" => println(state)
}
}
SamplePersistentModel.scala:
sealed trait UserAction
case object Add extends UserAction
case object Remove extends UserAction
case class UserUpdate(userId: String, action: UserAction)
sealed trait Event
case class AddUserEvent(userId: String) extends Event
case class RemoveUserEvent(userId: String) extends Event
case class ActiveUsers(users: Set[String] = Set.empty[String])
{
def update(evt: Event)= evt match {
case AddUserEvent(userId) => copy(users + userId)
case RemoveUserEvent(userId) => copy(users.filterNot(_ == userId))
}
override def toString = s"$users"
}
My question
What is the purpose of = state (or = this.state if I'm correct) in line def updateState(event:Event) = state = state.update(event). Why can't we just use def updateState(event:Event) = state.update(event)?
Found similar in documentation example.
In your sample code:
def updateState(event: Event) = state = state.update(event)
is equivalent to:
def updateState(event: Event) = { state = state.update(event) }
So, updateState is a function of Event => Unit, which is exactly what method persist expects as its second parameter:
persist(AddUserEvent(userId))(updateState)
Below is the signature of method persist in Akka PersistentActor:
trait PersistentActor extends Eventsourced with PersistenceIdentity {
// ...
def persist[A](event: A)(handler: A => Unit): Unit = {
internalPersist(event)(handler)
}
// ...
}
It expects a EventType => Unit handler code block as its second parameter to handle specific persistence business logic that generally involves updating internal states of the actor.
Why can't we just use def updateState(event:Event) = state.update(event)?
The reason for the reassignment to the state variable is that update creates a new object. In other words, calling state.update doesn't mutate state; it makes a copy of state with the updated information.
This is the case with the example that you referenced:
var state = ExampleState()
def updateState(event: Evt): Unit =
state = state.updated(event)
Looking at the code for ExampleState, we see that the updated method actually creates a new ExampleState object:
def updated(evt: Evt): ExampleState = copy(evt.data :: events)

How extend behaviour of super actor in akka

I want to implement CRUD operation using akka actor. I am a new in akka so dont know the designing fundamentals of akka actors.
I want to share the behaviours of akka actors in multiple sub actors.
Fir example i want to save and delete student , teacher and other entity.
I have created actor for StudentDao.scala
class StudentDao extends Actor with ActorLogging{
override def Receive = {
case Add(student) =>
// Add to database
case Delete =>
//Delete from database
// Some other cases related to Student entity
}
}
case object StudentDao{
case class Add(user : Student)
case class Delete(id : String)
}
Same I have actor for TeacherDao.scala
class TeacherDao extends Actor with ActorLogging{
override def Receive = {
case Add(teacher) =>
// Add to database
case Delete =>
//Delete from database
// Some other cases related to teacher entity
}
}
object TeacherDao{
case class Add(user : teacher)
case class Delete(id : String)
}
I want to abstract delete method for both dao.
So i have create BaseDao.scala
class BaseDao extends Actor with ActorLogging{
override def Receive = {
case Delete =>
//Delete from database dao.delete
}
how can i abstract using base actor.
orElse is the way to extend actor behaviors, because an actor's Receive is simply an alias for PartialFunction[Any, Unit]. Below is a concrete illustration with your use case.
First, define the base behavior in a trait that must be mixed in with an actor. To avoid duplication, move the Delete case class into this trait's companion object.
trait BaseDao { this: Actor with ActorLogging =>
import BaseDao._
def baseBehavior: Receive = {
case Delete(id) =>
log.info(s"Deleting $id from db")
// delete from db
}
}
object BaseDao {
case class Delete(id: String)
}
Then, mix in the above trait into your other actors and chain the behaviors with orElse. Note that I created dummy Student and Teacher case classes so that this code would compile. StudentDao:
class StudentDao extends Actor with ActorLogging with BaseDao {
import StudentDao._
def studentBehavior: Receive = {
case Add(student) =>
log.info(s"Adding student: $student")
// some other cases related to Student
}
def receive = studentBehavior orElse baseBehavior
}
object StudentDao {
case class Add(user: Student)
}
case class Student(name: String)
And TeacherDao:
class TeacherDao extends Actor with ActorLogging with BaseDao {
import TeacherDao._
def teacherBehavior: Receive = {
case Add(teacher) =>
log.info(s"Adding teacher: $teacher")
// some other cases related to Teacher
}
def receive = teacherBehavior orElse baseBehavior
}
object TeacherDao {
case class Add(user: Teacher)
}
case class Teacher(name: String)
You can create a trait for the base actor, with a common receive function orElse another one that has to be implemented in sub actors:
trait BaseActor extends Actor {
override def receive: Receive = commonReceive orElse handleReceive
def commonReceive: Receive = {
case CommonMessage => // do something
}
def handleReceive: Receive
}
And then your sub actors only have to implement handleReceive:
class SubActor extends BaseActor {
override def handleReceive: Receive = {
case SpecificMessage => // do something
}
}

General Finite State Machine (Transducer) in Scala

What is the general way to implement a finite state machine (or finite state transducer) in Scala?
I often find myself in need for state machine implementation. My typical implementation looks like
object TypicalFSM { // actually — finite state transducer
type State
case object State1 extends State
case object State2 extends State
type Message
case object Message1 extends Message
type ResultMessage
case object ResultMessage1 extends ResultMessage
}
import TypicalFSM._
class TypicalFSM extends ((Message) =>Seq[ResultMessage]){
var state:State = State1
def apply(message:Message):Seq[ResultMessage] = (state, message) match {
case (State1, Message1) =>
state = State2
Seq(ResultMessage1, ResultMessage2)
}
}
What I dislike is the mutable var which makes the solution thread unsafe. Also the FSM topology is not clear.
How to create FSMs in a functional way?
It also would be very good to draw FSM-graph in .dot format
Akka FSM has a good property of allowing to associate some Data with a State, not only giving an object name. This is also appreciated.
(However, Akka FSM is not always convenient to use as it is asynchronous and sometimes a bit heavy-weight.)
This is probably not what you are looking for, but I think it's an interesting concept.
object TypicalFSM {
sealed trait State
final class State1 extends State
final class State2 extends State
sealed trait Message
case class Message1(s: String) extends Message
case class Message2(s: String) extends Message
sealed trait ResultMessage
object ResultMessage1 extends ResultMessage
object ResultMessage2 extends ResultMessage
}
import TypicalFSM._
case class Transformation[M <: Message, From <: State, To <: State](
f:M => Seq[ResultMessage]) {
def apply(m:M) = f(m)
}
object Transformation {
implicit def `message1 in state1` =
Transformation[Message1, State1, State2] { m =>
Seq(ResultMessage1, ResultMessage2)
}
implicit def `message1 in state2` =
Transformation[Message1, State2, State2] { m =>
Seq(ResultMessage1)
}
implicit def `message2 in state2` =
Transformation[Message2, State2, State1] { m =>
Seq(ResultMessage2)
}
}
class TypicalFSM[CurrentState <: State] {
def apply[M <: Message, NewState <: State](message: M)(
implicit transformWith: Transformation[M, CurrentState, NewState]) = {
this.asInstanceOf[TypicalFSM[NewState]] -> transformWith(message)
}
}
Usage would be like this:
def test() = {
val s1 = new TypicalFSM[State1]
// type of s1: TypicalFSM[State1]
val (s2, r1) = s1(Message1("m1"))
// type of s2: TypicalFSM[State2]
val (s3, r2) = s2(Message1("m1"))
// type of s2: TypicalFSM[State2]
val (s4, r3) = s2(Message2("m2"))
// type of s2: TypicalFSM[State1]
// val (s5, r4) = s4(Message2("m2"))
// Fails with:
// 'No transformation available for TypicalFSM.Message2 in TypicalFSM.State1'
// type of s5: TypicalFSM[State1]
}
Your use case would strongly determine the structure of the code in this concept. The use case really determines how much type information you want to keep.
I this concept because the state is kept using the type system and that illegal transitions are reported at compile-time.

Composing trait behavior in Scala in an Akka receive method

Consider these two traits:
trait Poked extends Actor {
override def receive = {
case Poke(port, x) => ReceivePoke(port, x)
}
def ReceivePoke(port: String, x: Any)
}
trait Peeked extends Actor {
override def receive = {
case Peek(port) => ReceivePeek(port)
}
def ReceivePeek(port: String)
}
Now consider I can create a new Actor that implements both traits:
val peekedpoked = actorRef(new Actor extends Poked with Peeked)
How do I compose the receive handlers? i.e., the receiver should be something like the following code, though "automatically generated" (i.e., all traits should compose):
def receive = (Poked.receive: Receive) orElse (Peeked.receive: Receive) orElse ...
You can use super[T] to reference members of particular super classes/traits.
For example:
trait IntActor extends Actor {
def receive = {
case i: Int => println("Int!")
}
}
trait StringActor extends Actor {
def receive = {
case s: String => println("String!")
}
}
class IntOrString extends Actor with IntActor with StringActor {
override def receive = super[IntActor].receive orElse super[StringActor].receive
}
val a = actorOf[IntOrString].start
a ! 5 //prints Int!
a ! "Hello" //prints String!
Edit:
In response to Hugo's comment, here's a solution that allows you to compose the mixins without having to manually wire their receives together. Essentially it involves a base trait with a mutable List[Receive], and each mixed-in trait calls a method to add its own receive to the list.
trait ComposableActor extends Actor {
private var receives: List[Receive] = List()
protected def registerReceive(receive: Receive) {
receives = receive :: receives
}
def receive = receives reduce {_ orElse _}
}
trait IntActor extends ComposableActor {
registerReceive {
case i: Int => println("Int!")
}
}
trait StringActor extends ComposableActor {
registerReceive {
case s: String => println("String!")
}
}
val a = actorOf(new ComposableActor with IntActor with StringActor).start
a ! 5 //prints Int!
a ! "test" //prints String!
The only thing to keep in mind is that the order of the receives should not be important, since you won't be able to easily predict which one is first in the chain, though you could solve that by using a mutable hashmap instead of a list.
You can use empty Receive in base actor class and chain receives in their definitions.
Sample for Akka 2.0-M2:
import akka.actor.Actor
import akka.actor.Props
import akka.event.Logging
import akka.actor.ActorSystem
class Logger extends Actor {
val log = Logging(context.system, this)
override def receive = new Receive {
def apply(any: Any) = {}
def isDefinedAt(any: Any) = false
}
}
trait Errors extends Logger {
override def receive = super.receive orElse {
case "error" => log.info("received error")
}
}
trait Warns extends Logger {
override def receive = super.receive orElse {
case "warn" => log.info("received warn")
}
}
object Main extends App {
val system = ActorSystem("mysystem")
val actor = system.actorOf(Props(new Logger with Errors with Warns), name = "logger")
actor ! "error"
actor ! "warn"
}