42 votes

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

J'aimerais savoir s'il existe un mécanisme à Akka qui peut faire exécuter un acteur périodiquement ?

65voto

kerryjj Points 251

Vous n'avez pas vraiment besoin d'un acteur pour faire cela dans Akka 1.3.1, vous pouvez programmer 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'appelleriez ainsi

 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 celui-ci

 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())

22voto

mattinbits Points 8632

L'approche utilisant la planification est une bonne approche, même s'il est possible que les messages se mettent en file d'attente si le travail effectué dans les délais est si important qu'il peut prendre plus de temps que l'intervalle planifié. Si vous souhaitez que l'intervalle se produise entre la fin d'une itération et le début de la suivante, utilisez alors 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 = ???
}

3voto

Brett Tofel Points 46

Exemple Java plus complet :

 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() { ... }
}

2voto

Amit Yadav Points 371

Si quelqu'un veut du code Java, il peut faire comme ça

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X