Как мне исполнять актера Акка каждые 5 минут? - PullRequest
41 голосов
/ 15 марта 2012

Я хотел бы знать, есть ли какой-нибудь механизм в Акке, который может периодически выполнять актера?

Ответы [ 4 ]

63 голосов
/ 25 марта 2012

Вам не нужен актер, чтобы сделать это в Akka 1.3.1, вы можете запланировать вызов функции каждые 5 минут, например:

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

Однако, если вы хотите, чтобы он был актером по другим причинам, вы бы назвали это так

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)

Если вы используете Akka 2.0, то это будет сделано так

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

Или отправлять актеру сообщение каждые 5 минут, как это

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())
21 голосов
/ 27 июля 2015

Подход, использующий расписание, является одним хорошим подходом, хотя существует вероятность того, что сообщения будут поставлены в очередь, если работа, выполняемая по расписанию, настолько велика, что это может занять больше запланированного интервала.Если вы хотите, чтобы интервал происходил между end одной итерации и начало следующей, то используйте scheduleOnce со следующей схемой:

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 = ???
}
3 голосов
/ 29 марта 2018

Более полный пример Java:

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() { ... }
}
2 голосов
/ 29 июля 2016

Если кому-то нужен Java-код, он может сделать это

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