web-dev-qa-db-fra.com

Comment puis-je faire exécuter un acteur Akka toutes les 5 minutes?

Je voudrais savoir s'il existe un mécanisme dans Akka qui peut faire exécuter périodiquement un acteur?

41
Evans Y.

Vous n'avez pas vraiment besoin d'un acteur pour le faire dans Akka 1.3.1, vous pouvez planifier une fonction à appeler toutes les 5 minutes comme ceci:

Scheduler.schedule(() => println("Do something"), 0L, 5L, TimeUnit.MINUTES)

Cependant, si vous voulez que ce soit un acteur pour d'autres raisons, vous l'appellerez comme ceci

case class Message()

val actor = actorOf(new Actor {
  def receive = {
    case Message() => println("Do something in actor")
  }
}).start()

Scheduler.schedule(actor, Message(), 0L, 5L, TimeUnit.MINUTES)

Si vous utilisez Akka 2.0, cela se ferait comme ceci

val system = ActorSystem("MySystem")
system.scheduler.schedule(0 seconds, 5 minutes)(println("do something"))

Ou envoyez un message à un acteur toutes les 5 minutes comme ceci

case class Message()
class MyActor extends Actor {
  def receive = { case Message() => println("Do something in actor") }
}

val system = ActorSystem("MySystem")
val actor = system.actorOf(Props(new MyActor), name = "actor")
system.scheduler.schedule(0 seconds, 5 minutes, actor, Message())
64
kerryjj

L'approche utilisant la planification est une bonne approche, bien que les messages puissent être mis en file d'attente si le travail effectué selon le calendrier est si important qu'il peut prendre plus de temps que l'intervalle planifié. Si vous voulez que l'intervalle se produise entre fin d'une itération et début de la suivante, utilisez scheduleOnce avec le modèle suivant:

import akka.actor.Actor
import scala.concurrent.duration._

class SchedulingActor extends Actor {

  override def preStart(): Unit = {
    self ! "Do Some Work"
  }

  def receive = {
    case "Do Some Work" => 
      doWork
      context.system.scheduler.scheduleOnce(5 minutes, self, "Do Some Work")
  }

  def doWork = ???
}
22
mattinbits

Plus complet Java exemple:

import akka.actor.AbstractActor;
import akka.actor.ActorRef;
import scala.concurrent.duration.FiniteDuration;
import Java.util.concurrent.TimeUnit;

public class AnActor extends AbstractActor {
    private final FiniteDuration SCHEDULED_WORK_DELAY = new FiniteDuration(5, TimeUnit.MINUTES);

    @Override
    public void preStart() {
        getSelf().tell("Do Scheduled Work", ActorRef.noSender());
    }

    @Override
    public Receive createReceive() {
        return receiveBuilder()
        .matchEquals("Do Scheduled Work", work -> {
            doScheduledWork();
         context().system().scheduler().scheduleOnce(SCHEDULED_WORK_DELAY, getSelf(),
                "Do Scheduled Work", context().dispatcher(), ActorRef.noSender());
        })
        .build();
    }

    private void doScheduledWork() { ... }
}
3
Brett Tofel

Si quelqu'un veut Java code alors ils peuvent faire comme ça

    Cancellable cancellable = system.scheduler().schedule(Duration.Zero(), Duration.create(5, TimeUnit.MINUTES), cronActor, "tick", system.dispatcher(), null);
2
Amit Yadav