Akka Send Delayed Message to self cannot Find implicit ExecutionContext - scala

I am using Akka 2.1.4. I need one of my actors to send a delayed message to itself.
I have tried, from within the Actor's receive:
context.system.scheduler.scheduleOnce(1 second, self, msg)
However, it does not compile, since it cannot find the implicit ExecutionContext. Where can I get it from?.
NOTE: I am aware that the actual sender will not be my actor, but that is OK, since I don't need to know who the sender is.

You could also do it like this:
class MyActor extends Actor{
import context._
...
}
This way you are assured that you are getting the dispatcher assigned to that actor in case it differs from the main dispatcher for the system (which is what you are getting with your solution).

I think I have found it:
import myActorSystem.dispatcher
context.system.scheduler.scheduleOnce(1 second, self, msg)
Now it compiles.

Related

What is the difference between timers.startSingleTimer and scheduler.scheduleOnce in Akka Actor?

I am designing an actor that should schedule sending a message to itself.
I notice that there are at least two ways to do it.
I would like to understand the difference to choose the right one.
The first is one method of akka.actor.Timers:
def startSingleTimer(key: Any, msg: Any, timeout: FiniteDuration): Unit
The second is the pretty common way with scheduler of actor context system:
final def scheduleOnce(
delay: FiniteDuration,
receiver: ActorRef,
message: Any)(implicit executor: ExecutionContext,
sender: ActorRef = Actor.noSender): Cancellable
Question:
Which is the main difference between them in case of scheduling a
message to itself?
Is it a good idea to pass actor context to scheduleOnce method?
akka.actor.Timers.startSingleTimer
Can be used only within an actor
Allows only scheduling a message to self, ie not possible to schedule a message to some other actors
If actor dies, the active timers are cancelled automatically
Keeps track of active timers by user provided key
context.system.scheduler.scheduleOnce
Can be used to schedule messages outside and inside actors
Requires explicit ActorRef for receiver and optional sender
There is no automatic clean-up process. All should be handled explicitly by calling returned akka.actor.Cancellable
So, if you just need to schedule messages to itself, pick akka.actor.Timers
Is it a good idea to pass actor context to scheduleOnce method?
Not sure in what way you want to do it, but in general actor context must be used only within receive method and not passed outside of an actor neither used in callback methods of Futures.

How to get an ActorRef from "this"

Lets say you have an actor class:
class MyActor extends Actor { }
And somewhere within MyActor, you'd like to pass it to another actor. But, you need "this" as an ActorRef. Since "this" is of type Actor, it can not be passed where ActorRef is required.
So the question is, how can an Actor ("this") get a reference to itself as an ActorRef? Is this even possible, or am I totally misunderstanding something...
From an Actor you can use self to get the ActorRef
If you know the path of an actor and you want to know its ActorRef then you can obtain it. You just have to create an actor using the actor selection and then send an Identity(none) message to that actor. It will send its ActorRefas a reply.
You find a more detailed explanation here: https://doc.akka.io/docs/akka/snapshot/actors.html

Terminates all other actors once one actor finishes its work

I am pretty new to scala and akka. I wonder to ask terminates all other actors once one of the actor finishes its work.
The basic structure of the code is as below. There is a Master who takes in charge of 5 workers, which are generated by a RoundRobinPool. Every worker is doing some work and will send the result back to the Master. What I need to realize is to let the Master to terminate all other workers once one of them finishes its work and send it back to the Master. The master then will send some relative value to the main function and then the whole program terminates.
Any idea how to implement this?
//Code:
object X{
sealed trait Message
case class Result() extends Message
case class Work() extends Message
case class Result() extends Message
case class Totalresult() extends Message
class Worker extends Actor{
def receive={
case Work =>
sender ! Result}
}//End of class Worker
class Master(nrOfWorkers: Int) extends Actor{
val workerRouter =context.actorOf(RoundRobinPool(nrOfWorkers).props(Props[Worker])))
def receive={
case Calculate => calculateSender=sender
case Result => calculateSender ! Totoalresult()
}
}//End of class Master
def main(args: String) {
val system =ActorSystem("mysystem")
val master=system.actorOf(Props(new Master(5),name="master")
val future=master ? Calculate
}
}
One of the major supervisionary aspects of Akka is that a given actor is considered responsible for its children. In this case, that means that the death of the "Master" actor will automatically result in termination of all its children, so all you really need to do is have the "Master" actor terminate itself. This can be done in a number of ways, such as through a Kill or or PoisonPill message to itself - eg, adding the line: self ! PoisonPill straight after sending the TotalResult message back to calculateSender.
Note that in the particular scenario you have described in your code, you set up to receive a future of a result in your main, but don't include any processing (eg. an onComplete call, or using Await) of that result. You could, in such processing, include a call to system.shutdown() rather than having the "Master" terminate itself, which would then terminate all the actors as part of the shutdown process - just be sure to call that only after the future (and hence the actor effort behind it) has completed.
PS: see this question for more info about the differences between the different ways of terminating an actor.

Akka and Actor behavior interface

I just start trying myself out with Scala. I grow confident enough to start refactoring an ongoing multi-threaded application that i have been working on for about a year and half.
However something that somehow bother and i can't somehow figure it out, is how to expose the interface/contract/protocole of an Actor? In the OO mode, i have my public interface with synchronized method if necessary, and i know what i can do with that object. Now that i'm going to use actor, it seems that all of that won't be available anymore.
More specifically, I a KbService in my app with a set of method to work with that Kb. I want to make it an actor on its own. For that i need to make all the method private or protected given that now they will be only called by my received method. Hence the to expose the set of available behavior.
Is there some best practice for that ?
To tackle this issue I generally expose the set of messages that an Actor can receive via a "protocol" object.
class TestActor extends Actor {
def receive = {
case Action1 => ???
case Action2 => ???
}
}
object TestActorProtocol {
case object Action1
case object Action2
}
So when you want to communicate with TestActor you must send it a message from its protocol object.
import example.TestActorProtocol._
testActorRef ! TestActorProtocol.Action1
It can become heavy sometimes, but at least there is some kind of contract exposed.
Hope it helps

garbage collecting scala actors

Scenario: I have this code:
class MyActor extends Actor {
def act() {
react {
case Message() => println("hi")
}
}
}
def meth() {
val a = new MyActor
a.start
a ! Message()
}
is the MyActor instance garbage collected? if not, how do i make sure it is? if I create an ad-hoc actor (with the 'actor' method), is that actor GCed?
This thread on the scala-user mailing list is relevant.
There Phillip Haller mentions using a particular scheduler (available in Scala 2.8) to enable termination of an Actor before garbage collection, either on a global or per-actor basis.
Memory leaks with the standard Actor library has lead to other Actor implementations. This was the reason for David Pollak and Jonas Boner's Actor library for Lift that you can read much more about here: http://blog.lostlake.org/index.php?/archives/96-Migrating-from-Scala-Actors-to-Lift-Actors.html
Have you tried adding a finalize method to see whether it is? I think the answer here is that the actors subsystem behaves no different to how you would expect it to: it does not cache any reference to your actor except in a thread-local for the duration of processing.
I would therefore expect that your actor is a candidate for collection (assuming the subsystem correctly clears out the ThreadLocal reference after the actor has processed the message which it does indeed appear to do in the Reaction.run method).