我想知道Akka中是否有任何可以定期执行演员的机制?
答案 0 :(得分:62)
你真的不需要演员在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())
答案 1 :(得分:20)
使用计划的方法是一种很好的方法,但如果按计划完成的工作如此之大以至于可能需要比计划的时间间隔更长的时间,则消息可能会排队。如果您希望在一次迭代的 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 = ???
}
答案 2 :(得分:3)
更完整的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() { ... }
}
答案 3 :(得分:2)
如果有人想要java代码,那么他们可以这样做
Cancellable cancellable = system.scheduler().schedule(Duration.Zero(), Duration.create(5, TimeUnit.MINUTES), cronActor, "tick", system.dispatcher(), null);