0

I have the following code that I need to run around 100 times:

   val system = ActorSystem("mySystem")
   val myActorObject = system.actorOf(Props[MyActorClass], name = "myactor")
   implicit val timeout = Timeout(60 seconds)
   val future = myActorObject ? Request1
   val result = Await.result(future, timeout.duration)

Question is: assuming the first two statements can be called just once, should I cache these variables or Akka does it?

ps0604
  • 1,227
  • 23
  • 133
  • 330
  • 1
    I don't think Akka is caching something. However you can create your Actor at the start up of your application and retrieve it later. Moreover you can inject the ActorSystem in your function. – Rémi Lavolée Nov 15 '16 at 14:22
  • What do you need to call 100 times? this line: __myActorObject ? Request1__? If thats the case you could do it inside a function, an actor or whetever you want. It depends what do you want to achieve. So, what do you want to do? create 100 actors? call an actor 100 times? Anyways you could need to pass the system as implicit: __def f(request: String)(implicit system: ActorSystem) = ???__ – fGo Nov 15 '16 at 17:25
  • @fGo no, I need to create the actor the first time I call it and use the same actor the remaining 99 times it is called – ps0604 Nov 15 '16 at 20:07

2 Answers2

1

Do not make the actor system creation and actor creation part of repetitive code. Once the actor is created. Using the ActorRef can be done as many times as possible.

val system = ActorSystem("mySystem")
val myActorObject = system.actorOf(Props[MyActorClass], name = "myactor")

Something like this

val futureList = for(_ <- 1 to 1000) yield {
  implicit val timeout = Timeout(60 seconds)
  val future = myActorObject ? Request1
}

val finalF = Future.sequence(futureList)

val result = Await.result(future, timeout.duration)
Nagarjuna Pamu
  • 14,737
  • 3
  • 22
  • 40
  • how to I wrap the system and actor creation in a function? – ps0604 Nov 15 '16 at 20:32
  • You do not need to wrap them inside a function. Just create the actor system during the starting of your program and then create as many actor as you need. But do not create more than one actor systems. – Nagarjuna Pamu Nov 15 '16 at 20:35
  • I'm using Play, wouldn't creating the system/actor at the beginning of the program (as a class constructor) create a race condition? – ps0604 Nov 15 '16 at 20:48
  • @ps0604 The old version of play. ActorSystem is created in Global object. In latest version of play you just inject it into the class constructor using `@Inject` annotation – Nagarjuna Pamu Nov 15 '16 at 20:51
1

In play! (+2.5.x) you can get the system by injection. e.g.

@Singleton
class MyController @Inject() (system: ActorSystem) extends Controller {

  val myActor = system.actorOf(MyActorClass.props, "myactor")

  //...
}

Then you could have an end point to call the actor as many times as you want, for example

def sayHello(name: String) = Action.async {
  (myActor ? name).map { message => Ok(message) }
}

The code inside your actor could be something like this

class MyActorClass extends Actor {
   def receive = {
    case name: String => sender() ! s"hello $name"
  }
}

object MyActorClass {
    def props: Props = Props(classOf[MyActorClass ])
}
fGo
  • 1,146
  • 5
  • 11
  • Why are you using `Action.async` ? I usually define a `receive` method to run the actor actions.Why did you define a @Singleton? – ps0604 Nov 16 '16 at 10:34
  • @ps0604 I defined it async because the result is a Future[Result]. Your second question can be answered by http://stackoverflow.com/questions/37282792/why-use-singleton-over-scalas-object-in-play-framework – fGo Nov 16 '16 at 10:48
  • @ps0604 the _receive_ function goes inside the actor code. What i'm showing you here is the Play Controller used to send messages to the actor. – fGo Nov 16 '16 at 13:49
  • what's the meaning of `(myActor ? name).map { message => Ok(message) }`, why the use of `map` ? – ps0604 Nov 17 '16 at 21:00
  • _?_ is an alias for ask. According to the doc: ```? sends a message asynchronously and returns a Future representing a possible reply. Also known as ask.```. So, you get a Future[String], then you replace the content of the future to a valid Play! result: _Future[result]_ , hence the _map_ – fGo Nov 18 '16 at 09:21