web-dev-qa-db-ja.com

Akkaアクターを5分ごとに実行するにはどうすればよいですか?

Akkaにアクターを定期的に実行できるメカニズムがあるかどうか知りたいのですが?

41
Evans Y.

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

スケジュールを使用する方法は、適切な方法の1つですが、スケジュールに従って実行される作業が非常に大きく、スケジュールされた間隔よりも長くかかる場合は、メッセージがキューイングされる可能性があります。ある反復のendと次の反復のbeginningの間に間隔を発生させる場合は、次のパターンで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 = ???
}
22
mattinbits

より完全な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
Brett Tofel

Javaコードが必要な場合は、このようにすることができます

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