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

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.

Related

How to pass behavior to Akka actor

I'm building Akka app which will retrieve RSS feeds (XML) from several sites. For each site I will create some class which will transform XML to some generalized object (Scala case class) with common fields from all RSS feeds:
case class RssFeed(title: String, ...)
trait RssTransformer {
def getRssFeed(): Seq[RssFeed]
}
class FooTransformer(...) extends RssTransformer {
override def getRssFeed(): : Seq[RssFeed] = {...}
}
class BarTransformer(...) extends RssTransformer {
override def getRssFeed(): : Seq[RssFeed] = {...}
}
And I want create Akka actors and pass to each of them some implementation of transformer (for example one actor will work with BarTransformer, another with FooTransformer etc).
The problem is that I'm using DI framework (Spring) to initiate actors, so I can't pass transformers through actor`s constructor parameters. The only way is to pass it using some Message, but passing behavior in messages is anti-pattern in Akka.
Can you please advice me how I can solve this problem, or even better if you can give me some adviсe on how to improve app architecture to avoid this problem?
Thanks
I'm not sure what you mean by "so I can't pass transformers through actor's constructor parameters." With spring you can use the constructor-arg element to provide constructor arguments.
If the problem is you must create Actors using the ActorSystem#actorOf method, one solution would be to define your own Factory Bean that takes an ActorSystem and some Props as constructor arguments and constructs your Actor.

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.

Unit Testing AKKA actors

I am doing a web application with Scala and Akka actors and I'm having some troubles with the tests.
In my case I need to taste an actor who talks with the Database. To do the unit testing I would like to use a Fake Database but I can't replace the new with my desired fake object.
Let's see some code:
Class MyActor extends Actor {
val database = new Database()
def receive = { ... }
}
And in the tests I would like to inject a FakeDatabase object instead Database. I've been looking in Internet but the best that I found is:
Add a parameter to the constructor.
Convert the val database to a var so in the test I could access the attribute by the underlying and replace it.
Both solutions solve the problem but are very dirty.
Isn't a better way to solve the problem?
Thanks!
The two primary options for this scenario are:
Dependency Injection Use a DI framework to inject a real or mock service as needed. In Akka: http://letitcrash.com/post/55958814293/akka-dependency-injection
Cake Pattern This is a Scala-specific way of achieving something akin to dependency injection without actually relying on injection. See: Akka and cake pattern
Echoing the advice here, I wouldn't call injecting the database in the constructor dirty. It might have plenty of benefits, including decoupling actor behaviour from the particular database instance.
However if you know there is only ONE database you will be always using in your production code, then think about defining a package level accessible constructor and a companion object returning a Props object without parameters by default.
Example below:
object MyActor {
def props() : Props = Props(new MyActor(new Database()))
}
class MyActor private[package](database : IDatabase) extends Actor {
def receive = { ... }
}
In this case you will still be able to inject the test database in your tests case (given the same package structure), but prevent users of your code from instantiating MyActor with unexpected database instance.

How to overload bang(!) operator in Scala Actor model?

In an Actor model implementation in Scala, can we override the bang(!) operator.
Can we modify the operation of message passing by overloading this operator?
Example scenario:
I need to include logging of information when any actor invokes another
actor by passing a message. So by overloading the message pass(!) operator, Can I
track the message passing between different actors and avoid including logger
statement for every actor message passing call?
In an Actor model implementation in Scala, can we override the bang(!) operator.
You can, but I would strongly recommend against it.
Example scenario: I need to include logging of information when any actor invokes another actor by passing a message.
This won't work with any actors which don't extend your type: Akka system actors, actors created by libraries, etc.
This can already be done by Akka, just set akka.debug.receive = on.
In Akka you cannot actually override the ! operator, since you cannot create subclasses of ActorRef in a meaningful way (i.e. they would not be generated by the respective factory methods), and the reason for this is that it is not actually what you want (please trust me here).
Your stated use-case is already covered by built-in functionality:
import akka.event.LoggingReceive
def receive = LoggingReceive {
case x => ...
}
which will log a message for each invocation if you enable these configuration settings:
akka {
loglevel = DEBUG
actor.debug {
receive = on // this enables the above
autoreceive = on // same for the likes of PoisonPill, Kill, …
lifecycle = on // will log actor creation, restart, termination
}
}
You can try the following code.
override def !(msg:Any):Unit =
{
//logic for writing to logs..
super.!(msg)
}
This works fine. However, i want to differentiate behavior of !, depending upon the messages I am sending. for example below:
actor_name!(arg1,arg2,arg3)
actor_name1!(arg4, arg5)
How do i differentiate between these two message sending notation in the overriding code?

Akka actors + Play! 2.0 Scala Edition best practices for spawning and bundling actor instances

My app gets a new instance of Something via an API call on a stateless controller. After I do my mission critical stuff (like saving it to my Postgres database and committing the transaction) I would now like to do a bunch of fire-and-forget operations.
In my controller I send the model instance to the post-processor:
import _root_.com.eaio.uuid.UUID
import akka.actor.Props
// ... skip a bunch of code
play.api.libs.concurrent.Akka.system.actorOf(
Props[MySomethingPostprocessorActor],
name = "somethingActor"+new UUID().toString()
) ! something
The MySomethingPostprocessorActor actor looks like this:
class MySomethingPostprocessorActor extends Actor with ActorLogging {
def receive = {
case Something(thing, alpha, beta) => try {
play.api.libs.concurrent.Akka.system.actorOf(
Props[MongoActor],
name = "mongoActor"+new UUID().toString()
) ! Something(thing, alpha, beta)
play.api.libs.concurrent.Akka.system.actorOf(
Props[PubsubActor],
name = "pubsubActor"+new UUID().toString()
) ! Something(thing, alpha, beta)
// ... and so forth
} catch {
case e => {
log.error("MySomethingPostprocessorActor error=[{}]", e)
}
}
}
}
So, here's what I'm not sure about:
I know Actor factories are discouraged as per the warning on this page. My remedy for this is to name each actor instance with a unique string provided by UUID, to get around the your-actor-is-not-unique errors:
play.core.ActionInvoker$$anonfun$receive$1$$anon$1:
Execution exception [[InvalidActorNameException:
actor name somethingActor is not unique!]]
Is there a better way to do the above, i.e. instead of giving everything a unique name? All examples in the Akka docs I encountered give actors a static name, which is a bit misleading.
(any other comments are welcome too, e.g. the if the bundling pattern I use is frowned upon, etc)
As far as I'm aware the name paramater is optional.
This may or may not be the case with Akka + Play (haven't checked). When working with standalone actor systems though, you usually only name an actor when you need that reference for later.
From the sounds of it you're tossing out these instances after using them, so you could probably skip the naming step.
Better yet, you could probably save the overhead of creating each actor instance by just wrapping your operations in Futures and using callbacks if need be: http://doc.akka.io/docs/akka/2.0.3/scala/futures.html