Scala akka how create entry point for event source? - scala

I've been struggling to learn akka actors and I REALLY need your help guys!
So my goal is basically to write a simple auction agent. And AKKA actually has an example on how to do it https://doc.akka.io/docs/akka/current/typed/replicated-eventsourcing-auction.html! The problem is, I have no idea how to run it. Now I've spent like 3 days on trying to get it to work before asking for your help but I've completely lost it..:/
So, I started to learn about typed actors first and how they work. I've managed to actually print something on the screen by creating a simple actor system like this that I've found on the internet where I have a simple order actor (typed) and on its apply method I can print the incoming order:
//Entry point inside main(args <...>)
val orderProcessor: ActorSystem[OrderProcessor.Order] = ActorSystem(OrderProcessor(), "main")
//create a new order
orderProcessor ! Order(0, "Bananas")
//<..printing something inside the actor when receiving this message>
Now the auction example uses EventSourcedBehavior so I came to the conclusion that next step is to learn about event sourcing in Akka (hopefully this isn't confusing so far or hopefully I'm on the right path) So I went to the official documentation of Akka's event sourcing https://doc.akka.io/docs/akka/current/typed/persistence.html#module-info and I took their example:
object MyPersistentBehavior {
sealed trait Command
final case class Add(data: String) extends Command
case object Clear extends Command
sealed trait Event
final case class Added(data: String) extends Event
case object Cleared extends Event
final case class State(history: List[String] = Nil)
val eventHandler: (State, Event) => State = { (state, event) =>
event match {
case Added(data) => state.copy((data :: state.history).take(5))
case Cleared => State(Nil)
}
}
val commandHandler: (State, Command) => Effect[Event, State] = { (state, command) =>
command match {
case Add(data) => Effect.persist(Added(data))
case Clear => Effect.persist(Cleared)
}
}
def apply(id: String): Behavior[Command] =
EventSourcedBehavior[Command, Event, State](
persistenceId = PersistenceId.ofUniqueId(id),
emptyState = State(Nil),
commandHandler = commandHandler,
eventHandler = eventHandler)
}
Now that is great! Very simple and concise.
The problem is, I don't understand where the entry point is?
Like for orderProcessor (first example that I've shown) it is obviously just to create a new ActorSystem and thats it, but I can't find any information on this example. I've tried soooo many different projects from github and none of them very simple enough for me to understand. To be fair most of them had tests, but tests didn't really help me much.
Please, any help, any tips would be SOOO much appreciated, I'm really struggling guys!
Love Yall !<3

You have to obtain ActorRef[MessangeType] to be able to send MessageType to it.
Existing actor has context (passed as an argument with Behavior definition) where you can create a child like:
val actorRef = context.spawn(behavior)
but you can also create it top-level from ActorSystem (then the system is the parent directly)
val actorRef = system.systemActorOf(behavior)
So in your case it could be something like:
val actorRef = system.systemActorOf(MyPersistentBehavior("test"))
actorRef ! MyPersistentBehavior.Add("test")
alternatively you can context.spawn it inside Behavior[OrderProcessor.Order] defined for your ActorSystem, then you'll talk to actorRef through system which would send commands to persistent actor.

I understand your paint, unfortunately Akka Documentation give only Snippets as samples in documentation and they are most of the time not complete and hard to understand.
You can find in their Github complete examples I guess you can understands things better this way.
If you want to see a full fledged Proof of Concept application with Akka, I have a blog about it which you can find here.

Related

Request-Response with the ask pattern

I am fairly new to Akka and went through this request-response example of the Akka documentation.
I understood this pattern works like the following:
Dave asks Hal by sending a message of Hal's protocol.
Hal answers by sending a message of its own protocol to Dave.
Dave, who does not know Hal's protocol gets the response adapted and re-sent to itself.
Dave receives the adapted response and continues with its payload.
context.ask(dave, Dave.Request) {
case Failure(exception) => throw exception
case Success(response) => AdaptedResponse(response.payload)
}
But what happens, if Dave needs response.payload diretly on the spot? Is this even possible?
In Akka Typed, it's not possible using context.ask, though I would question why you specifically need it.
As an alternative, when you have two actors which interact, you can define a joint-protocol between them:
object Hal {
sealed trait Command
sealed trait CommandFromDave extends Command {
def replyTo: ActorRef[Dave.ResponseFromHal]
}
case class OpenThePodBayDoorsPlease(override val replyTo: ActorRef[Dave.ResponseFromHal]) extends CommandFromDave
}
object Dave {
sealed trait Command
sealed trait ResponseFromHal extends Command
case class MessageFromHal(msg: String) extends ResponseFromHal
}
Then Dave can just
hal ! Hal.CommandFromDave(context.self)
and get the response directly from Hal (and you can schedule a message to yourself to account for the timeout).
Note that this really entangles two actors together. It's suitable for cases like where a parent actor defers a long-running task to a child actor, but it's a really questionable approach in most/all other scenarios.

Play WebSocketActor createHandler with custom name

I am using (learning to) handle websockets in play application.
My controller is using WebSocket.acceptWithActor
def clientWS = WebSocket.acceptWithActor[JsValue, JsValue] { _ =>
upstream => ClientSesssionActor.props(upstream)
}
and all is well except some other "supervisor" actor needs to be able to use context.actorSelection(...) to communicate with all/some of those ClientSessionActors.
But all my ClientSessionActors are created with a path like this one :
[akka://application/system/websockets/ REQ_ID /handler]
Here is the line where WebsocketActorSupervisor creates them :
val webSocketActor = context.watch(context.actorOf(createHandler(self), "handler"))
That is where the "handler" part of the path comes from.
I would like to pass in a specific name for my ClientSessionActor instead of getting "handler".
Overloading the whole call stack with one more parameter seems inelegant: there is WebSocketActor.scala with Connect, WebSocketActorSupervisor(props and constructor), WebSocketsActor receive and then everything inside the WebSocket.scala.
I know I can pass the supervisor reference to the props, but what about the case when the "supervisor" has been restarted and needs to reconnect with his minions.
One more thing, I realize that I might be able to get all the "handler" actors, but there are more than 2 kinds of handlers. Yes I could have them ignore msgs directed at the other groups of handlers but this just feels so redundant sending out 3 times more msgs than I should have to.
Any suggestions ?
James ? :)
Thank you
How about each ClientSesssionActor sends a Register message to supervisor on preStart and store them in eg. val sessions = new HashMap[String, ActorRef].
And then unregister by sending Unregister in postStop
private class WebSocketsActor extends Actor {
import WebSocketsActor._
def receive = {
case c # Connect(requestId, enumerator, iteratee, createHandler) =>
implicit val mt = c.messageType
context.actorOf(WebSocketActorSupervisor.props(enumerator, iteratee, createHandler),
requestId.toString)
}
}
Here is code how play creates actors for handling websockets, it names with requestId.
I have also same question :) why not make it to name with custom names.

Is there a way to avoid untyped ActorRef in scala cookbook actor communication example?

In scala cookbook: 13.3. How to Communicate Between Actors I see this
class Ping(pong: ActorRef) extends Actor { // OMG - ActorRef - no type, help!
var count = 0
def incrementAndPrint { count += 1; println("ping") }
def receive = {
case StartMessage =>
incrementAndPrint
I have got also a few places in my own code where I have this ActorRef I don't like it as I liked type safety. Is there a way to avoid that in the above pong example?
Side Note: I understand I can use "actorFor" with naming, but as a DI freak I rather pass it in constructor / parameter.
Some stuff is in the works for Akka 3.0 eg see this teaser thread: https://mobile.twitter.com/RayRoestenburg/status/510511346040197120
There is a pattern for type safety now using a custom ask (the question mark). Here is a blog about it:
http://www.warski.org/blog/2013/05/typed-ask-for-akka/
This is a little clunky though and may not be worth the trouble.
Another approach is to create typed APIs and wrap your actors in them.

Rewrite the Scala actors in Akka

Update: I've rewritten it in wonky-style and posted it on github - I would appreciate some feedback: https://github.com/drozzy/parallel-discrete-event-akka/tree/master/src/main/scala
Can anyone help me re-write "Parallel discrete event simulation" example from the "Chapter 32: Actors and Concurrency" from Programming in Scala, 2nd, by Martin Odersky?
It was written originally in Scala actors, but translating to Akka I encouter a lot of problems.
Some examples
Actor inheritance (p. 708)
Code like this:
trait Simulant extends Actor
class Wire extends Simulant
I have no idea how to translate to Akka, since in my understanding we never directly instantiate them.
Main Loop
The author constantly uses loops in actors, and I have no idea what they are about:
def act() {
loop {
if (running && busySimulants.isEmpty)
advance()
reactToOneMessage()
}
}
Types
Mostly though, I am struggling with strong types -- it seems Akka, due to requiring ActorRefs prevents me from depending on a specific type of an actor. For example, in the book, the following:
trait Simulant extends Actor {
val clock: Clock
...
depends on a strongly-typed actor Clock. And then it is simply "instantiated" in the implementing actor:
class Wire(name: String, init: Boolean) extends Simulant {
def this(name: String) { this(name, false) }
def this() { this("unnamed") }
val clock = Circuit.this.clock
In my implementation I have something along the lines of:
trait Simulant extends Actor {
val clock: ActorRef
...
and I have no idea how to "instantiate" it. What I have now (untested) is:
class Wire(val clock:ActorRef, name:String, init: Boolean) extends Actor{
def this(clock:ActorRef, name:String) {this(clock, name, false)}
def this(clock:ActorRef){this(clock, "unnamed")}
so I just end up draggin the actor refs around the constructors!
Hooking up components
How do I hook up components to each other? For example, hook-up an AndGate to a Wire - such that any time a signal on the wire changes it sends a message to the gate.
I do it by sending Add messages (i.e. AndGate sends Add to Wire so that wire can add it to the list of its subscribers), and so have to wait for all of them to arrive before starting the simulation. Is there any way to avoid that (the waiting)? (In original implementation the with Scala Actors, some actors were just accessed from global scope, and sometimes actors called other actor's methods directly!)
Source Code
The source code of the example can be found in full at the following url:
http://booksites.artima.com/programming_in_scala_2ed/examples/html/ch32.html
under the heading: 32.6 A longer example: Parallel discrete event simulation
P.S.: I'm new to akka, so forgive my ignorance.
I can not provide any migrated source code, but this link might help you:
actors migration guide.
Some comments:
Actor Inheritance
You can do this in Akka, but class Wire has to implement the receive method.
Main Loop
In Akka you implement the receive method instead of the main loop.
Types
You can use an ActorRef as constructor parameter, but it has to be created (and started) before calling the constructor, e.g. with context.system.actorOf(...).
And there is something called Typed Actors in Akka.
I also strongly encourage you to have a look at the documentation.
EDIT
I had a (quick) look at the source code, these are my findings:
In Scala it is not so common as in Java (and not enforced) that only one public class exists per file (although it can improve compile speed).
Demo.scala: Line 11, Use var instead of val
Constructor initialization (e.g. in FullAdder, Gate, ...): You should be careful about
that, because the constructor is executed every time the actor is restarted; maybe using
the preStart method would be better.
FullAdder, HalfAdder: An actor who doesn't react to messages (or only returning Unit) is a
strange thing in my opinion. Maybe you find another solution for constructing an adder.
Clock.advance: Using return is not good scala style (and I believe it doesn't work
in this case). Use else instead.

Alternatives to using "var" for state with actors?

I have found myself using vars fairly often with akka actors to maintain state. For example, if I my actor needs to maintain a list of items, I might do something like:
class ListActor extends Actor{
var xs : List[Int] = List()
def receive = {
case x : Int => xs = x :: xs
}
}
Using the mutable variable seems to go against the spirit of Scala. Alternatively I have used this:
class ListActor2 extends Actor{
import context._
def collect_ints(accu : List[Int]) : Receive = {
case x : Int => become(collect_ints(x :: accu))
}
def receive = collect_ints(Nil)
}
I like how this looks more, but do I have to worry about the stack overflowing?
I am aware of the FSM trait and have used that before also, but for some situations it seems like too much.
What is the recommended way of maintaining simple state? Are there other alternatives that I am unaware of?
Also, is it generally a bad sign if I find myself needing mutable variables often? Am I not using the actor model properly?
I don´t see any problem with var for simple state in the actor model.
By design Akka prevents the actor´s state of getting corrupted or locked by concurrent access to the state variables.
As long as you are not exposing your state to other threads with the use of Future for instance, the use of var for simple state should not be a problem.
There are two variants of the become method: one that pushes behavior onto a stack, and one that doesn't. The latter is the default, so you don't have to worry about the behavior stack becoming too large. Using become to manage state in this manner is a perfectly valid use for it.
The Akka FSM is actually a very compact idiom for maintaining state in an actor system as in this example:
sealed trait State
case object Active extends State
class ListActor extends Actor with FSM[State,List[Int]] {
startWith(Active,List[Int]())
when(Active) {
case Event(x:Int,xs) => stay using x :: xs
}
}
Having used all the alternatives discussed here, FSM takes my vote for anything that is a shade more complex than trivial.