19

Akka初心者です。毎日決まった時刻、たとえば午前 8 時にタスクをスケジュールする必要があります。私が知っている方法は、たとえば定期的にタスクをスケジュールすることです

import akka.util.duration._

scheduler.schedule(0 seconds, 10 minutes) {
  doSomething()
}

Akka で 1 日の決まった時間にタスクをスケジュールする最も簡単な方法は何ですか?

小括弧

この機能を使用するだけで、やりたいことを簡単に実行できます。おもちゃの実装は次のようになります

scheduler.schedule(0 seconds, 24 hours) {
  val now = computeTimeOfDay()
  val delay = desiredTime - now

  scheduler.scheduleOnce(delay) {
    doSomething()
  }
}

難しいことではありませんが、レースコンディションを少し導入しました。実際、午前 8 時前にこれを起動するとどうなるか考えてみてください。外部閉鎖が開始されますが、私が計算するdelayまでには午前 8 時を過ぎている可能性があります。これは、すぐに実行されるはずの内部閉鎖が明日に延期され、実行が 1 日スキップされることを意味します。

この競合状態を修正する方法があります。たとえば、12 時間ごとにチェックを実行し、タスクをすぐにスケジュールする代わりに、一度に複数のタスクを受け入れないアクターに送信することができます。

しかし、おそらく、これは Akka や何らかの拡張機能に既に存在しています。

4

4 に答える 4

7

一度書いて、毎日実行する

val GatherStatisticsPeriod = 24 hours

private[this] val scheduled = new AtomicBoolean(false)

def calcBeforeMidnight: Duration = { 
  // TODO implement 
} 

def preRestart(reason: Throwable, message: Option[Any]) {
  self ! GatherStatisticsScheduled(scheduled.get)
  super.preRestart(reason, message)
}

def schedule(period: Duration, who: ActorRef) = 
  ServerRoot.actorSystem.scheduler
    .scheduleOnce(period)(who ! GatherStatisticsTick)

def receive = {

  case StartServer(nodeName) => 
    sender ! ServerStarted(nodeName)
    if (scheduled.compareAndSet(false, true)) 
      schedule(calcBeforeMidnight, self)

  case GatherStatisticsTick =>
    stats.update
    scheduled.set(true)
    schedule(GatherStatisticsPeriod, self) 

  case GatherStatisticsScheduled(isScheduled) =>
    if (isScheduled && scheduled.compareAndSet(false, isScheduled))
      schedule(calcBeforeMidnight, self)

}

Akka のスケジューラーは何らかの方法で再起動を内部的に処理していると思います。私は自分自身にメッセージを送信する非永続的な方法を使用しました - 実際には配信の厳密な保証はありません. また、ティックは異なる場合があるため、GatherStatisticsPeriod は関数である可能性があります。

于 2012-12-05T01:03:04.700 に答える
6

Akkaでこの種のスケジューリングを使用するには、 Akka Camelまたはakkaのこのプロトタイプクォーツを使用して、独自のスケジュールを作成するか、Quartzを使用する必要があります。

派手で非常に正確なものが必要ない場合は、希望する最初の時間までの遅延を計算し、それをスケジュール呼び出しの開始遅延として使用し、間隔を信頼します。

于 2012-12-05T11:29:57.987 に答える