Hasil yang benar-benar tidak dapat dijelaskan untuk penjadwal berbasis cron di Quartz

Kami memiliki kelas layanan yang bertanggung jawab untuk menjadwalkan pekerjaan berdasarkan masukan pengguna. Salah satu metode kelas tersebut menerima objek dengan input pengguna dan membuat ekspresi cron untuknya. Saya mulai membuat pengujian unit untuk setiap kasus penggunaan dan menemukan perbedaan yang benar-benar tidak dapat dijelaskan antara dua pengujian yang hampir identik:

Seseorang menguji kasus pekerjaan berulang setiap 2 hari:

"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
    }
    }

Dan itu berfungsi setiap saat tanpa masalah apa pun.

Dan satu lagi, menguji hal yang sama dengan interval 4 hari:

"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
    }

Yang terakhir berfungsi beberapa hari yang lalu, dan kemudian saya mulai mendapatkan kesalahan yang sama tanpa benar-benar mengubah apa pun.

'Rabu 13 Juli 05:57:00 UTC 2016' tidak sama dengan 'Senin 11 Juli 05:57:00 UTC 2016'

Kesalahan ini berarti bahwa tanggal penghitungan berikutnya bukanlah tanggal berjalan pertama, melainkan tanggal setelahnya. Mengapa ini terjadi? Apa yang saya lewatkan?


person Shurik Agulyansky    schedule 11.07.2016    source sumber


Jawaban (1)


Anda sepertinya bingung tentang bagaimana 1/4 diinterpretasikan dalam ekspresi cron. Pada kolom hari dalam bulan akan cocok dengan hari ke 1, 5, 9, 13, dst. Jadi ya, kalau "sekarang" adalah 11 Juli, pertandingan berikutnya adalah 13 Juli.

person Joe Pallas    schedule 11.07.2016
comment
Jadi, apakah ini berarti saya juga perlu mengetahui tanggal mulai ekspresi tersebut agar dapat berfungsi dengan benar? - person Shurik Agulyansky; 11.07.2016
comment
Itu sangat tergantung pada apa yang Anda coba lakukan. Jika Anda menginginkan jadwal setiap n hari, yang lebih cocok adalah CalendarInterval (lihat CalendarIntervalScheduleBuilder.withIntervalInDays) daripada CronExpression. - person Joe Pallas; 12.07.2016