Reputation: 163
I have an actor class, Manager extends UntypedActor
that contains a list of messages: listOfMessages
, a list of client WebSocket connections: clientConnections
, and a method sendMessagesToClient
that sends every message in listOfMessages
to every client, and then resets listOfMessages
to an empty list. I want the method sendMessagesToClient
executed every 2 seconds.
Is there a way to schedule a method to run on an interval from within an actor? Most docs only show how to schedule a task for a different actor, as shown here:
system.scheduler().schedule(
Duration.create(0, TimeUnit.MILLISECONDS), //Initial delay 0 milliseconds
Duration.create(30, TimeUnit.MINUTES), //Frequency 30 minutes
testActor,
"tick",
system.dispatcher(),
null
);
but I want something like this inside the Manager
class:
system.scheduler().schedule(
Duration.create(0, MILLISECONDS),
Durant.create(2, "seconds"),
sendMessagesToClient()
);
Is this possible?
Upvotes: 0
Views: 985
Reputation: 10428
Yes this is certainly possible. The method I prefer is to have the actor send a message to itself, and within the Receive, call the method which you want to have executed. For example (in Scala since that it how I use Akka):
class Example extends Actor {
override def preStart() {
system.scheduler().schedule(
Duration.create(0, TimeUnit.MILLISECONDS), //Initial delay 0 milliseconds
Duration.create(30, TimeUnit.MINUTES), //Frequency 30 minutes
self, //Send the message to itself
"tick",
system.dispatcher(),
null
);
}
def receive = {
case "tick" => sendMessagesToClient()
}
def sendMessagesToClient() {
//do work
}
}
This actor will, as soon as it starts, schedule the regular sending of the message "tick" to itself.
One of the advantages I see in handling the scheduling this way is that it queues the work done by "tick" along with any other work to be done by the Actor, so it helps to ensure that the Actor continues to perform only one task at once, keeping the thread safety within the actor.
Upvotes: 1