From a2baa1546f0c270545fee2e661c5bd13be837c3b Mon Sep 17 00:00:00 2001 From: Cam Saul <cammsaul@gmail.com> Date: Mon, 9 Jul 2018 16:46:13 -0700 Subject: [PATCH] Don't barf if task has already been scheduled --- src/metabase/task.clj | 5 ++++- src/metabase/task/send_pulses.clj | 23 +++++++++++------------ src/metabase/task/sync_databases.clj | 22 +++++++++++----------- 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/metabase/task.clj b/src/metabase/task.clj index c710cd8e5c2..f3e475749d4 100644 --- a/src/metabase/task.clj +++ b/src/metabase/task.clj @@ -99,7 +99,10 @@ "Add a given job and trigger to our scheduler." [job :- JobDetail, trigger :- Trigger] (when-let [scheduler (scheduler)] - (qs/schedule scheduler job trigger))) + (try + (qs/schedule scheduler job trigger) + (catch org.quartz.ObjectAlreadyExistsException _ + (log/info (trs "Job already exists:") (-> job .getKey .getName)))))) (s/defn delete-task! "delete a task from the scheduler" diff --git a/src/metabase/task/send_pulses.clj b/src/metabase/task/send_pulses.clj index b8765ce3c77..8c12234cace 100644 --- a/src/metabase/task/send_pulses.clj +++ b/src/metabase/task/send_pulses.clj @@ -63,26 +63,25 @@ [] ;; build our job (reset! send-pulses-job (jobs/build - (jobs/of-type SendPulses) - (jobs/with-identity (jobs/key send-pulses-job-key)))) + (jobs/of-type SendPulses) + (jobs/with-identity (jobs/key send-pulses-job-key)))) ;; build our trigger (reset! send-pulses-trigger (triggers/build - (triggers/with-identity (triggers/key send-pulses-trigger-key)) - (triggers/start-now) - (triggers/with-schedule - ;; run at the top of every hour - (cron/cron-schedule "0 0 * * * ? *")))) + (triggers/with-identity (triggers/key send-pulses-trigger-key)) + (triggers/start-now) + (triggers/with-schedule + ;; run at the top of every hour + (cron/cron-schedule "0 0 * * * ? *")))) ;; submit ourselves to the scheduler (task/schedule-task! @send-pulses-job @send-pulses-trigger)) -;;; ## ---------------------------------------- PULSE SENDING ---------------------------------------- - +;;; ------------------------------------------------- PULSE SENDING -------------------------------------------------- (defn- send-pulses! - "Send any `Pulses` which are scheduled to run in the current day/hour. We use the current time and determine the - hour of the day and day of the week according to the defined reporting timezone, or UTC. We then find all `Pulses` - that are scheduled to run and send them." + "Send any `Pulses` which are scheduled to run in the current day/hour. We use the current time and determine the hour + of the day and day of the week according to the defined reporting timezone, or UTC. We then find all `Pulses` that + are scheduled to run and send them." [hour weekday monthday monthweek] {:pre [(integer? hour) (and (<= 0 hour) (>= 23 hour)) diff --git a/src/metabase/task/sync_databases.clj b/src/metabase/task/sync_databases.clj index 3c1394e53f0..234ec36cd48 100644 --- a/src/metabase/task/sync_databases.clj +++ b/src/metabase/task/sync_databases.clj @@ -25,7 +25,7 @@ ;;; +----------------------------------------------------------------------------------------------------------------+ (s/defn ^:private job-context->database :- DatabaseInstance - "Get the Database referred to in JOB-CONTEXT. Guaranteed to return a valid Database." + "Get the Database referred to in `job-context`. Guaranteed to return a valid Database." [job-context] (Database (u/get-id (get (qc/from-job-data job-context) "db-id")))) @@ -68,27 +68,27 @@ ;; using them (s/defn ^:private job-key :- JobKey - "Return an appropriate string key for the job described by TASK-INFO for DATABASE-OR-ID." + "Return an appropriate string key for the job described by `task-info` for `database-or-id`." [task-info :- TaskInfo] (jobs/key (format "metabase.task.%s.job" (name (:key task-info))))) (s/defn ^:private trigger-key :- TriggerKey - "Return an appropriate string key for the trigger for TASK-INFO and DATABASE-OR-ID." + "Return an appropriate string key for the trigger for `task-info` and `database-or-id`." [database :- DatabaseInstance, task-info :- TaskInfo] (triggers/key (format "metabase.task.%s.trigger.%d" (name (:key task-info)) (u/get-id database)))) (s/defn ^:private cron-schedule :- cron-util/CronScheduleString - "Fetch the appropriate cron schedule string for DATABASE and TASK-INFO." + "Fetch the appropriate cron schedule string for `database` and `task-info`." [database :- DatabaseInstance, task-info :- TaskInfo] (get database (:db-schedule-column task-info))) (s/defn ^:private job-class :- Class - "Get the Job class for TASK-INFO." + "Get the Job class for `task-info`." [task-info :- TaskInfo] (:job-class task-info)) (s/defn ^:private trigger-description :- s/Str - "Return an appropriate description string for a job/trigger for Database described by TASK-INFO." + "Return an appropriate description string for a job/trigger for Database described by `task-info`." [database :- DatabaseInstance, task-info :- TaskInfo] (format "%s Database %d" (name (:key task-info)) (u/get-id database))) @@ -103,7 +103,7 @@ ;;; +----------------------------------------------------------------------------------------------------------------+ (s/defn ^:private delete-task! - "Cancel a single sync task for DATABASE-OR-ID and TASK-INFO." + "Cancel a single sync task for `database-or-id` and `task-info`." [database :- DatabaseInstance, task-info :- TaskInfo] (let [trigger-key (trigger-key database task-info)] (log/debug (u/format-color 'red "Unscheduling task for Database %d: trigger: %s" @@ -111,7 +111,7 @@ (task/delete-trigger! trigger-key))) (s/defn unschedule-tasks-for-db! - "Cancel *all* scheduled sync and FieldValues caching tassks for DATABASE-OR-ID." + "Cancel *all* scheduled sync and FieldValues caching tasks for `database-or-id`." [database :- DatabaseInstance] (delete-task! database sync-analyze-task-info) (delete-task! database field-values-task-info)) @@ -122,7 +122,7 @@ ;;; +----------------------------------------------------------------------------------------------------------------+ (s/defn ^:private job :- JobDetail - "Build a durable Quartz Job for TASK-INFO. Durable in Quartz allows the job to exist even if there are no triggers + "Build a durable Quartz Job for `task-info`. Durable in Quartz allows the job to exist even if there are no triggers for it." [task-info :- TaskInfo] (jobs/build @@ -135,7 +135,7 @@ (s/def ^:private field-values-job (job field-values-task-info)) (s/defn ^:private trigger :- CronTrigger - "Build a Quartz Trigger for DATABASE and TASK-INFO." + "Build a Quartz Trigger for `database` and `task-info`." [database :- DatabaseInstance, task-info :- TaskInfo] (triggers/build (triggers/with-description (trigger-description database task-info)) @@ -153,7 +153,7 @@ (cron/with-misfire-handling-instruction-fire-and-proceed))))) (s/defn ^:private schedule-tasks-for-db! - "Schedule a new Quartz job for DATABASE and TASK-INFO." + "Schedule a new Quartz job for `database` and `task-info`." [database :- DatabaseInstance] (let [sync-trigger (trigger database sync-analyze-task-info) fv-trigger (trigger database field-values-task-info)] -- GitLab