And*_*rea 19 scala scheduled-tasks akka
我是Akka的初学者.我需要每天在固定的时间安排一项任务,比如上午8点.我所知道的是如何定期安排任务
import akka.util.duration._
scheduler.schedule(0 seconds, 10 minutes) {
doSomething()
}
Run Code Online (Sandbox Code Playgroud)
在Akka一天中的固定时间安排任务的最简单方法是什么?
只需使用此功能就可以轻松完成我想要的操作.玩具实现看起来像
scheduler.schedule(0 seconds, 24 hours) {
val now = computeTimeOfDay()
val delay = desiredTime - now
scheduler.scheduleOnce(delay) {
doSomething()
}
}
Run Code Online (Sandbox Code Playgroud)
这并不难,但我介绍了一点竞争条件.事实上,考虑如果我在上午8点之前启动它会发生什么.外部闭合将开始,但到我计算时,delay我们可能会在上午8点之后.这意味着内部关闭 - 应该立即执行 - 将被推迟到明天,从而跳过执行一天.
有办法解决这种竞争条件:例如,我可以每12小时执行一次检查,而不是立即安排任务,将其发送给一次不接受多个任务的演员.
但可能,这已经存在于Akka或某些扩展中.
写一次,每天跑
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)
}
Run Code Online (Sandbox Code Playgroud)
我相信Akka的调度程序会以某种方式内部处理重启.我使用非持久的方式向自己发送消息 - 实际上没有严格的交付保证.此外,滴答可能会有所不同,因此GatherStatisticsPeriod可能是一个函数.
要在Akka中使用这种调度,您必须自己滚动或者通过Akka Camel或用于Akka的原型石英使用Quartz 。
如果您不需要任何花哨且非常准确的方法,那么我只需计算所需的第一次延迟,并将其用作计划调用的开始延迟,并信任该间隔。
假设您想每天下午13点运行任务。
import scala.concurrent.duration._
import java.time.LocalTime
val interval = 24.hours
val delay = {
val time = LocalTime.of(13, 0).toSecondOfDay
val now = LocalTime.now().toSecondOfDay
val fullDay = 60 * 60 * 24
val difference = time - now
if (difference < 0) {
fullDay + difference
} else {
time - now
}
}.seconds
system.scheduler.schedule(delay, interval)(doSomething())
Run Code Online (Sandbox Code Playgroud)
还请记住,服务器时区可能与您的时区不同。
| 归档时间: |
|
| 查看次数: |
11441 次 |
| 最近记录: |