Play Framework - 在精确的时间安排任务

时间:2016-07-07 09:02:33

标签: scala playframework akka

我正在做一个Scala-Play应用程序,我想安排一个任务在每天凌晨3点发送邮件,所以我为此创建了一个类,但是我没有工作:

class ManageSendInvalidateDaemon @Inject() (app: Application, emailSender: EmailSender, mailer: MailerClient) {
    Akka.system(app).scheduler.schedule(
    scala.concurrent.duration.Duration.create(20,TimeUnit.SECONDS),
    scala.concurrent.duration.Duration.create(60, TimeUnit.SECONDS),
    new Runnable(){
      override def run()={ 
         //Function to send the mail 
      }
   }
  );
};

我认为问题在于:

    scala.concurrent.duration.Duration.create(20,TimeUnit.SECONDS),
    scala.concurrent.duration.Duration.create(60, TimeUnit.SECONDS),

我真的不明白这两行的使用是什么

2 个答案:

答案 0 :(得分:3)

这不会像你期望的那样有效。 Akka调度程序只允许您指定任务的重复性,但不会指定它将运行的日期,小时等(例如:您可以告诉它每10分钟运行一次任务,但不会在每个星期一的15:30运行)。

这两行指示Akka每隔60秒运行一次该任务,并在定义后20秒内第一次运行(因此,如果在12h30m执行schedule调用,该任务将在12时首次运行:30:20然后12:31:20,12:32:20等。

要解决此问题,您只需要定期运行任务(例如,在每种情况下,每分钟),并检查当前小时。如果它是3AM发送这些电子邮件(并最终存储任何已执行此任务)。

另一种选择是使用类似akka-quartz-scheduler的东西,它允许您指定调度类型

答案 1 :(得分:0)

我遇到了同样的问题。所以我创建了一个方法来计算从现在到我想要运行

的时间
schedule = Akka.system().scheduler().schedule(
               Duration.create(nextRunTime(), TimeUnit.MILLISECONDS),
               Duration.create(DAY_IN_MS, TimeUnit.MILLISECONDS),
               ...,);

nextRunTime()方法计算在下一个凌晨3点之前的时间(以毫秒为单位),之后我设置一天的间隔(DAY_IN_MS)

private int nextRunTime() {
  String runTimeValue = "03:00";
  LocalTime now = new LocalTime();
  LocalTime runTime = new LocalTime(runTimeValue);
  int timeUntilRun;
  if (runTime.isAfter(now)) { // From now until the run time
    timeUntilRun = runTime.getMillisOfDay() - now.getMillisOfDay();
  } else { // From now until midnight, plus from midnight until the run time
    timeUntilRun = DAY_IN_MS - now.getMillisOfDay() + runTime.getMillisOfDay();
  }
  Logger.info("nextRunTime(): next run in " + timeUntilRun + " ms");
  return timeUntilRun;
}