Quartz 中基于 cron 的调度程序的绝对无法解释的结果
Absolutely unexplainable results for cron based scheduler in Quartz
我们有一项服务 class 负责根据用户输入安排作业。 class 的方法之一接受带有用户输入的对象并为其构建 cron 表达式。
我开始为每个用例创建单元测试,发现两个几乎相同的测试之间存在绝对无法解释的差异:
每 2 天测试一次重复作业的情况:
"ChecklistCreationScheduler#buildCronExpression" should {
"build correct cron expressions for day interval of 2" in {
val jobScheduler = mock[JobScheduler]
val futureChecklistRepository = mock[FutureChecklistRepository]
val chlCreationScheduler = new ChecklistCreationScheduler(jobScheduler, futureChecklistRepository)
val now = DateTime.now.withSecondOfMinute(0).withMillisOfSecond(0)
val dayIntervalForm = mock[CreateJobForm]
dayIntervalForm.maybeDayInterval returns Some(2)
val cronStr = chlCreationScheduler.buildCronExpression(List(dayIntervalForm), now)
cronStr must_== "0 %s %s 1/2 * ? *".format(now.getMinuteOfHour, now.getHourOfDay)
val cronExpression = new CronExpression(cronStr)
val firstRun = cronExpression.getNextValidTimeAfter(now.minusMinutes(1).toDate)
firstRun must_== now.toDate
cronExpression.getNextValidTimeAfter(firstRun) must_== now.plusDays(2).toDate
}
}
而且每次都能正常运行。
另一个,以 4 天的间隔测试同样的事情:
"build correct cron expressions for day interval of 4" in {
val jobScheduler = mock[JobScheduler]
val futureChecklistRepository = mock[FutureChecklistRepository]
val chlCreationScheduler = new ChecklistCreationScheduler(jobScheduler, futureChecklistRepository)
val now = DateTime.now.withSecondOfMinute(0).withMillisOfSecond(0)
val dayIntervalForm = mock[CreateJobForm]
dayIntervalForm.maybeDayInterval returns Some(4)
val cronStr = chlCreationScheduler.buildCronExpression(List(dayIntervalForm), now)
cronStr must_== "0 %s %s 1/4 * ? *".format(now.getMinuteOfHour, now.getHourOfDay)
val cronExpression = new CronExpression(cronStr)
val firstRun = cronExpression.getNextValidTimeAfter(now.minusMinutes(1).toDate)
firstRun must_== now.toDate
cronExpression.getNextValidTimeAfter(firstRun) must_== now.plusDays(4).toDate
}
几天前最后一个曾经工作过,然后我开始遇到同样的错误而没有真正改变任何东西。
'Wed Jul 13 05:57:00 UTC 2016' is not equal to 'Mon Jul 11 05:57:00
UTC 2016'
此错误意味着下一个计算日期不是第一个 运行 日期,而是之后的日期。为什么会这样?我想念什么?
您似乎对 cron 表达式中 1/4 的解释方式感到困惑。在日期字段中,它将匹配第 1、5、9、13 等天。所以,是的,如果 "now" 是 7 月 11 日,下一次匹配将是 7 月 13 日。
我们有一项服务 class 负责根据用户输入安排作业。 class 的方法之一接受带有用户输入的对象并为其构建 cron 表达式。 我开始为每个用例创建单元测试,发现两个几乎相同的测试之间存在绝对无法解释的差异:
每 2 天测试一次重复作业的情况:
"ChecklistCreationScheduler#buildCronExpression" should {
"build correct cron expressions for day interval of 2" in {
val jobScheduler = mock[JobScheduler]
val futureChecklistRepository = mock[FutureChecklistRepository]
val chlCreationScheduler = new ChecklistCreationScheduler(jobScheduler, futureChecklistRepository)
val now = DateTime.now.withSecondOfMinute(0).withMillisOfSecond(0)
val dayIntervalForm = mock[CreateJobForm]
dayIntervalForm.maybeDayInterval returns Some(2)
val cronStr = chlCreationScheduler.buildCronExpression(List(dayIntervalForm), now)
cronStr must_== "0 %s %s 1/2 * ? *".format(now.getMinuteOfHour, now.getHourOfDay)
val cronExpression = new CronExpression(cronStr)
val firstRun = cronExpression.getNextValidTimeAfter(now.minusMinutes(1).toDate)
firstRun must_== now.toDate
cronExpression.getNextValidTimeAfter(firstRun) must_== now.plusDays(2).toDate
}
}
而且每次都能正常运行。
另一个,以 4 天的间隔测试同样的事情:
"build correct cron expressions for day interval of 4" in {
val jobScheduler = mock[JobScheduler]
val futureChecklistRepository = mock[FutureChecklistRepository]
val chlCreationScheduler = new ChecklistCreationScheduler(jobScheduler, futureChecklistRepository)
val now = DateTime.now.withSecondOfMinute(0).withMillisOfSecond(0)
val dayIntervalForm = mock[CreateJobForm]
dayIntervalForm.maybeDayInterval returns Some(4)
val cronStr = chlCreationScheduler.buildCronExpression(List(dayIntervalForm), now)
cronStr must_== "0 %s %s 1/4 * ? *".format(now.getMinuteOfHour, now.getHourOfDay)
val cronExpression = new CronExpression(cronStr)
val firstRun = cronExpression.getNextValidTimeAfter(now.minusMinutes(1).toDate)
firstRun must_== now.toDate
cronExpression.getNextValidTimeAfter(firstRun) must_== now.plusDays(4).toDate
}
几天前最后一个曾经工作过,然后我开始遇到同样的错误而没有真正改变任何东西。
'Wed Jul 13 05:57:00 UTC 2016' is not equal to 'Mon Jul 11 05:57:00 UTC 2016'
此错误意味着下一个计算日期不是第一个 运行 日期,而是之后的日期。为什么会这样?我想念什么?
您似乎对 cron 表达式中 1/4 的解释方式感到困惑。在日期字段中,它将匹配第 1、5、9、13 等天。所以,是的,如果 "now" 是 7 月 11 日,下一次匹配将是 7 月 13 日。