Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use the Akka scheduler inside an actor?

I want to have the possibility to put actors to sleep for a while. The actors should decide themselves how long they are going to sleep. As Thread.sleep() is not a recommended way of doing this I thought of using the scheduler in akka. I therefore defined an actor were another actor can register for being woken up.

class Scheduler extends Actor {    def receive = {     case Sleep(duration) => context.system.scheduler.scheduleOnce(duration) {       sender ! Ring     }   } } 

But the sending actor never receives the Ring message. So my questions are

  • Is scheduling with the scheduler recommended inside an actor?
  • Why is the sending actor never receiving the Ring message?
  • If this is not possible what is the recommended way of solving the problem?
like image 886
Felix Reckers Avatar asked Dec 15 '12 22:12

Felix Reckers


People also ask

Can an Akka actor stop other actors?

In Akka, you can stop Actors by invoking the stop() method of either ActorContext or ActorSystem class. ActorContext is used to stop child actor and ActorSystem is used to stop top level Actor.

How does Akka work internally?

Akka ensures that each instance of an actor runs in its own lightweight thread and that messages are processed one at a time. In this way, each actor's state can be reliably maintained without the developer needing to explicitly worry about synchronization or race conditions.

Is Akka used for scheduling in spark?

Spark uses Akka basically for scheduling. All the workers request for a task to master after registering. The master just assigns the task. Here Spark uses Akka for messaging between the workers and masters.


1 Answers

Let me first answer the title question: yes, it is possible to use the scheduler inside an actor.

case Sleep(duration) =>   context.system.scheduler.scheduleOnce(duration, self, Ring) 

Now to the question behind the question

You did not say what you actually want to achieve, so I’m making an educated guess here that you want the actor—which normally does something called “X”—to do something called “Y” for a while, suspending the “X” activity. The full solutions to this would be

class Sleepy extends Actor {   def receive = {      ... // cases doing “X”      case Sleep(duration) =>       case object WakeUp       context.system.scheduler.scheduleOnce(duration, self, WakeUp)       context.become({         case WakeUp => context.unbecome()         // drop the rest       }, discardOld = false)   } } 

The same could as well be implemented using the FSM trait and switching between the normal and the sleeping state. And of course you can do whatever you want while sleeping, e.g. mix in the Stash trait in Akka 2.1 and call stash() for all (or some) messages while sleeping, unstashAll() when getting the WakeUp message; or you could do something else altogether. Actors are very flexible.

What actors don’t do

Actors never really sleep, they always handle incoming messages. As shown above, you can define what that means, but the basic principle is that you cannot suspend an actor such that it will not process the messages in its mailbox.

like image 173
Roland Kuhn Avatar answered Sep 18 '22 17:09

Roland Kuhn