Я хотел бы знать, есть ли в Akka какой-либо механизм, который может периодически запускать актера?
Как я могу казнить актера Akka каждые 5 минут?
Ответы (4)
Вам действительно не нужен актор для этого в 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())
scheduleOnce
с некоторой дополнительной логикой.
- person matanster; 13.07.2016
context.system.scheduler.schedule(<params>)
, чтобы выполнить свою работу по планированию.
- person NateH06; 18.04.2018
Подход с использованием расписания является одним из хороших подходов, хотя сообщения могут ставиться в очередь, если работа, выполняемая по расписанию, настолько велика, что может занять больше времени, чем запланированный интервал. Если вы хотите, чтобы интервал возникал между концом одной итерации и началом следующей, используйте 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 = ???
}
context.system.scheduler.schedule(...)
для отправки сообщений self
каждые 5 минут? Это выглядело бы намного чище и избавило бы от необходимости переопределять preStart
.
- person Branislav Lazic; 05.06.2017
Более полный пример 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() { ... }
}
Если кому-то нужен java-код, они могут сделать так
Cancellable cancellable = system.scheduler().schedule(Duration.Zero(), Duration.create(5, TimeUnit.MINUTES), cronActor, "tick", system.dispatcher(), null);