Search code examples
clojurequartzite

Clojure - schedule a job every Tuesday


I am using quartzite, and I need to schedule a job every tuesday morning (say at 10 AM).

I have the code for the job, but I'm not sure how to schedule it.

Edit : Here is what I have so far, but it doesn't work (see comment).

(defn start-weekly-email-job []
  (let [job  (job/build
              (job/of-type AlertMail)
              (job/with-identity (job/key "jobs.weekly.1")))
        trigger (trigger/build
                 (trigger/with-identity (trigger/key "triggers.1"))
                 (trigger/start-at (time-of-day 10 00 00))
                                        ; at 10 AM, fails with exception
                                        ; IllegalArgumentException No implementation of method: :to-date of protocol: #'clojurewerkz.quartzite.conversion/DateConversion found for class: org.quartz.TimeOfDay  clojure.core/-cache-protocol-fn (core_deftype.clj:554)
                 (trigger/with-schedule (daily/schedule
                                         (daily/on-days-of-the-week #{(int 2)}))))] ;; ;; start Tuesday
    (qs/schedule s job trigger)))

Edit2 :

Using daily interval schedules Daily interval schedules make it easy to define schedules like

  • "Monday through Friday from 9 to 17"
  • "Every weekend at 3 in the morning"
  • "Every Friday at noon"
  • "Every day at 13:45"
  • "Every hour on Thursdays but not later than 15:00, up to 400 times total"

My case is very similar from the case highlighted in the documentation, yet I can't find how to do it with the daily schedules.


Solution

  • One viable option is to use cron triggers[1][2][3]. Sample code from the documentation [1] -

    (ns my.service
      (:require [clojurewerkz.quartzite.scheduler :as qs]
                [clojurewerkz.quartzite.triggers :as t]
                [clojurewerkz.quartzite.jobs :as j]
            [clojurewerkz.quartzite.jobs :refer [defjob]]
                [clojurewerkz.quartzite.schedule.cron :refer [schedule cron-schedule]]))
    
    (defjob NoOpJob
      [ctx]
      (comment "Does nothing"))
    
    (defn -main
      [& m]
      (let [s   (-> (qs/initialize) qs/start)
           job  (j/build
                  (j/of-type NoOpJob)
                  (j/with-identity (j/key "jobs.noop.1")))
            trigger (t/build
                      (t/with-identity (t/key "triggers.1"))
                      (t/start-now)
                      (t/with-schedule (schedule
                                         (cron-schedule "0 0 15 ? * 5"))))]
      (qs/schedule s job trigger)))
    

    Cron schedules use the local timezone of the machine on which it is scheduled. Something like 0 0 10 ? * TUE describes every Tuesday at 10am as per the machines local time. If the time needs to be some specific UTC time, then the preferable option would be to pre-calculate the corresponding local time and use that in the cron trigger description. Or just configure the machine to use UTC timezone.

    [1] - http://clojurequartz.info/articles/triggers.html#using_cron_expression_schedules

    [2] - [DEAD] http://quartz-scheduler.org/generated/2.2.1/html/qs-all/index.html#page/Quartz_Scheduler_Documentation_Set%2Fco-trg_crontriggers.html%23

    [3] - http://linux.die.net/man/5/crontab

    [4] - Possible replacement for now dead link no 2 - http://www.quartz-scheduler.org/documentation/quartz-2.x/tutorials/tutorial-lesson-06.html