I'm evaluating Akka for a distributed service layer, the following example prints Hello {n} 10 times, but does it one after the other. As I understand it this is intentional for an Akka actor, so where do I go from here to make it concurrent?
import akka.actor._
object HelloActor {
case class SayHello(message: String)
}
class HelloActor extends Actor {
def receive = {
case HelloActor.SayHello(message) =>
Thread.sleep(1000)
println(message)
}
}
object Main extends App {
val system = ActorSystem("ActorSystem")
val hello = system.actorOf(Props[HelloActor])
for (i <- 1 to 10) {
hello ! HelloActor.SayHello(s"Hello $i")
}
}
I've experimented with creating multiple actors from the Main class but that feels wrong somehow, shouldn't I just call the actor then it handles concurrency / spawning more actors on its own? Could anyone provide an example of this (preferably modifying the above code). I've been reading and reading but it feels like a lot to take in immediately and I feel I'm just missing a key concept here somewhere.
For your use case you'll probably want to use Routers.
For example:
val hello = system.actorOf(Props[HelloActor].withRouter(
RoundRobinRouter(nrOfInstances = 10)))
hello ! HelloActor.SayHello("Hello!") // Sends to one of the 10
As a side note, you should avoid blocking (ie. Thread.sleep) in your actor's receive method.
As #sourcedelica mentioned in the comments, routing is probably what you want to do. A simple refactor to your example using a RoundRobinRouter could look like this:
import akka.actor._
import akka.routing._
object HelloActor {
case class SayHello
}
class HelloActor extends Actor {
def receive = {
case HelloActor.SayHello =>
println(s"saying hello from: ${self.path}")
}
}
object Main extends App {
val system = ActorSystem("ActorSystem")
val hello = system.actorOf(Props[HelloActor].withRouter(RoundRobinRouter(10)))
for (i <- 1 to 10) {
hello ! HelloActor.SayHello
}
}
This is a pretty simple example as it's using a simple router (round robin) and it's non-resizing. You can do a lot more with the routers and I highly suggest reading up on them more at:
http://doc.akka.io/docs/akka/2.2.3/scala/routing.html
Related
I have an old Scala/Akka Http project that I'm trying to simplify and refactor. I was wondering if there's a better way to organize routes and perhaps split them across actors. Here's what I have at the moment (far from ideal):
```
object MyAPI {
def props(): Props = Props(new MyAPI())
val routes = pathPrefix("api") {
pathPrefix("1") {
SomeActor.route //More routes can be appended here using ~
}
}
}
final class MyAPI extends Actor with ActorLogging {
implicit lazy val materializer = ActorMaterializer()
implicit lazy val executionContext = context.dispatcher
Http(context.system)
.bindAndHandleAsync(Route.asyncHandler(MyAPI.routes), MyHttpServer.httpServerHostName, MyHttpServer.httpServerPort)
.pipeTo(self)
override def receive: Receive = {
case serverBinding: ServerBinding =>
log.info(s"Server started on ${serverBinding.localAddress}")
context.become(Actor.emptyBehavior)
case Status.Failure(t) =>
log.error(t, "Error binding to network interface")
context.stop(self)
}
}
```
```
object SomeActor {
def props(): Props = Props[SomeActor]
val route = get {
pathPrefix("actor") {
pathEnd {
complete("Completed") //Is there a clean way 'ask' the actor below?
}
}
}
}
class SomeActor extends Actor with ActorLogging {
implicit lazy val executionContext = context.dispatcher;
override def receive: Receive = {
//receive and process messages here
}
```
So, my question is - is there a clean way to structure and refactor routes instead of lumping them together in one large route definition? I could perhaps create a hierarchy of actors (routers) and the main route definition just delegates it to the routers and we incrementally add more details as we go deeper in the actor hierarchy. But is there a generally accepted patter or two to organize routes?
I would like to suggest you on the basis of the functionality you can have as many actors you you want, but create one supervisor actors which will keep watch on each child actor. And all the supervision strategies should be written into the supervisor itself, and all the msg you gonna sent to the actors should be forwarded by the supervisor.
As soon as you get the data from the end point, may be get or post method take the data into someRequest case class. Then sent it to some handleReq() method. And then do your processing make traits on functionality basis.
You can structure project something like this.
src/
actor//all the actors will be in this package
model// all the case classes and constants
repo// all the db related function you can do here
service// all your routes and endPoint functions
Now you can have package util where all the utilities trait you can put which will be used by any of the actor, or service may be you have lots of validations you can have a package named validator.
The structure is depends on your business. I think it would help.
The Akka Typed Actors documentation states that it will be superseded by Akka Typed. I am inferring from this that Akka Typed can be used to implement the Active Object pattern; but it is not too clear to me how. Here is my attempt so far; I'm aware it stinks :D
object HelloWorld {
final case class Greet(whom: String, replyTo: ActorRef[Greeted])
final case class Greeted(whom: String)
private val greeter = Static[Greet] { msg ⇒
println(s"Hello ${msg.whom}!")
msg.replyTo ! Greeted(msg.whom)
}
private val system = ActorSystem("HelloWorld", Props(greeter))
def greet(whom: String): Future[Greeted] = system ? (Greet(whom, _))
}
Cheers
The Active Object Pattern as defined by the page you link to is not desirable for all the reasons why TypedActors are being removed: the fact that a method is executed asynchronously is so important that it should not be hidden by technologies like proxy objects that implement normal interfaces. Instead, Akka Typed allows you to write nearly the same code as if it was an Active Object while retaining the asynchronous marker: instead of selecting a method with the . syntax you send a message using ? (or ! if the protocol is not simple request–response). Your example would look like this:
object HelloWorld {
final case class Greet(whom: String)(replyTo: ActorRef[Greeted])
final case class Greeted(whom: String)
val greeter = Static[Greet] { msg ⇒
println(s"Hello ${msg.whom}!")
msg.replyTo ! Greeted(msg.whom)
}
}
object Sample extends App {
import HelloWorld._
val system = ActorSystem("HelloWorld", Props(greeter))
val fg = system ? Greet("John")
}
Please note that creating a separate thread (or ActorSystem) per object may sound okay as per the classical pattern, but doing that foregoes many of the benefits of a message-driven architecture, namely that many Actors can share the same resources for more efficient execution and they can form supervision hierarchies for principled failure handling etc.
I have a singleton actor system in my application, and this works perfectly fine except that when the same application is loaded and unloaded inside the same JVM for testing, I have an error because I try, in my startup procedure, to recreate an actor which already exists.
As a result I get an akka.actor.InvalidActorNameException because the Actor name is not unique.
I am looking for a way to smoothly shutdown the actors depending on the actor systems without shutting down the actor system itself. Which is a reasonable strategy for that?
This is not exactly answer to your question - "... a way to smoothly shutdown the actors ...", but you mentioned that you are able to able to start two applicatons in same JVM.
Could you make your actor system to be singleton within application instance instead of singleton within whole JVM?
You would have two independent actor systems, you won't have name conflicts and won't have to start/stop specific actors.
I guess problems could be if some of actors are interacting with outside world, for example consuming some messages from JMS etc. Then it would not be obvious which actor system is processing them.
Do you want somethings like this ?
object AkkaTest extends App {
import akka.actor._
import akka.pattern.ask
import akka.util.Timeout
import scala.concurrent.duration._
val system = ActorSystem.create
val supervisor = system.actorOf(Props[MasterOfPuppets], name = "masterOfPuppets")
private object AllTerminated
private class MasterOfPuppets extends Actor {
var supervised = 0
var waiterForTerminated: Option[ActorRef] = None
def receive = {
case actor: ActorRef =>
context.watch(actor)
supervised += 1
case Terminated(dead) =>
supervised -= 1
if (supervised == 0) {
waiterForTerminated.map(_ ! AllTerminated)
waiterForTerminated = None
}
case AllTerminated =>
if (supervised == 0) {
sender ! AllTerminated
} else {
waiterForTerminated = Some(sender)
}
}
}
private class TestedActor extends Actor {
def receive = {
case a: Any => sender ! a
}
}
implicit val timeout = Timeout(5.seconds) // needed for `?` below
// Create first actor
val actor1 = system.actorOf(Props[TestedActor], name = "name1")
supervisor ! actor1
actor1 ! PoisonPill
val waitForIt = supervisor ? AllTerminated
Await.result(waitForIt, 5.seconds)
// Same name
val actor2 = system.actorOf(Props[TestedActor], name = "name1")
supervisor ! actor2
println("ok then")
}
Your problem is very simple : Akka and message are asynchronous. If you try to create an actor just after you kill him, the name is not available.
Try just a Thread.sleep before creating new actor and it will work.. :)
I am writing a program using Actors in scala in which an actor (Actor1) accepts two numbers as command line arguments and sends a message to another actor Actor2 (which calculates their sum). Actor2 sends the result to Actor1, who prints it on the screen.
class Actor1 extends Actor {
def main(args: Array[String]) {
val n= Integer.parseInt(args(0))
val k= Integer.parseInt(args(1))
val actor2 = new Actor2
actor2 ! (n, k)
}
def act()
{
react{
case num: Integer =>
println(num)
case _=>
println("Sum not received")
exit
}
}
}
class Actor2 extends Actor {
def act(){
loop
{
react
{
case(n:Int, k:Int) =>
val i = n + k
val actor1 = new Actor1
actor1 ! i}
}
}
}
Is it possible to define main() inside the class that extends Actor, and is there any other way to accept command line arguments by the Actor?
It shows the error: class Actor1 needs to be abstract, since method act in trait Reactor of type ()Unit is not defined.
First things first: You should consider using akka instead of the default Scala actors. It's just better.. in pretty much every aspect.
That aside, here are a few answers for your:
Your main method should be in a standalone object (not a companion object). So use something like this: object Main { def main(args:Array[String]) { ... } } and start your program via the Main object/class. (This is due to the definition inside the Actor1 class being non-static and the problem that if you define a companion object the .class filenames collide.)
In your code, something seems to have gone wrong with the brackets - or did you place Actor2 inside the Actor1 class on purpose? It's cleaner, if you just make three separate classes/objects: Actor1, Actor2, Main.
When you create Scala actors, you have to explicitly start them (not so with akka 2.x). So you miss your calls to actor1.start and such. Note that your program will then not terminate before your actors have terminated, so don't wonder if it doesn't stop anymore after you add that.
Finally, some minor hints:
You may want to consider using !? and send back your answer to the original caller, as this also allows you to have a proper termination condition.
Integer.parseInt("0") can be written more simply as "0".toInt
Are there any guides or tutorials which explain the possibility to use scala actors remotely? All I have found until now is one example (without comments) but that's hardly enough.
I have written an article with an example app to explain the use of Remote Actors a bit some time ago.
Well, it has no comments inside the code (maybe you even meant that article), but there are explanations below the code.
Just be careful to send messages that are serializable (case classes and case objects are!) and be sure the opposite side can create the class.
Watch out for custom ClassLoaders or missing JARs in you classpaths.
None of which I am aware. It's pretty much a "hack your way through the jungle" approach. Judging from the API though, things should work pretty much the same as regular actors, for which there exist one or two tutorials (as well as a few books now).
If you do make use of remote actors, we (the community) would certainly welcome such a tutorial from an experienced user!
The Akka framework has remote actors. The API is pretty similar to regular scala actors.
They provide some level of automatic clustering as well, but it's not complete.
recently there was a guide added on the front page of www.scala-lang.org, here is the link
http://www.scala-lang.org/docu/files/actors-api/actors_api_guide.html#
Maybe this is a necropost but I was looking for all over and could not find much. Hopefully this will help someone.
I am running Mac OS 10.6.8 and Scala 2.9.0.1. I had problems getting the canonical remote actors example running. I ended up with the following code.
Note: The clear method is just to prevent messages from piling up. It's not critical to the example. Likewise the calls to Thread.sleep are just to make it easier to see what is going on at runtime.
Compile it, then in separate shell instances do:
$> scala Ping
and
$> scala Pong
in any order. You can experiment by killing one of them at a time and tracing the code.
import scala.actors._
import scala.actors.Actor._
import scala.actors.remote._
import scala.actors.remote.RemoteActor._
/** #author Connor Doyle */
// Remote messages must be serializable.
// The easist way to do this is to wrap
// them with a case class
case class Message(text: String)
abstract class PingPongActor extends Actor with App {
val pingPort = 9000
val pongPort = 9001
val delay = 1000
classLoader = getClass().getClassLoader() // hack!
start
// this method consumes all pending messages
// the library should have implemented an atomic
// receiveAndClear operation
def clear: Unit = receiveWithin(0) {
case TIMEOUT => ()
case _ => clear
}
}
object Ping extends PingPongActor {
// result of select already lazy, but explicit lazy conveys
// semantics clearly
lazy val pong = select(Node("localhost", pongPort), 'pong)
def act = {
alive(pingPort)
register('ping, self)
loop {
pong ! Message("ping")
receiveWithin(delay * 2) {
case Message(text: String) => {
clear
println("received: "+text)
Thread.sleep(delay) // wait a while
}
case TIMEOUT => println("ping: timed out!")
}
}
}
}
object Pong extends PingPongActor {
lazy val ping = select(Node("localhost", pingPort), 'ping)
def act = {
alive(pongPort)
register('pong, self)
loop {
receiveWithin(delay * 2) {
case Message(text: String) => {
println("received: "+text)
Thread.sleep(delay) // wait a while
clear
ping ! Message("pong")
}
case TIMEOUT => println("pong: timed out")
}
}
}
}
Cheers!