From 5191eef6f9386aab545cc462cecfc3faaf377c25 Mon Sep 17 00:00:00 2001 From: Derek Troy-West Date: Wed, 13 Jun 2018 23:39:23 +1000 Subject: [PATCH] fairly complete pluggable proxy-fn impl --- project.clj | 3 +- src/troy_west/cronut.clj | 30 ++--- test-resources/config.edn | 109 +++++++++--------- test/troy_west/cronut/integration_fixture.clj | 18 ++- 4 files changed, 93 insertions(+), 67 deletions(-) diff --git a/project.clj b/project.clj index de758bc..b8ae896 100644 --- a/project.clj +++ b/project.clj @@ -17,7 +17,8 @@ [integrant "0.6.3"]] :profiles {:dev {:resource-paths ["test-resources"] - :dependencies [[ch.qos.logback/logback-classic "1.2.3"]]}} + :dependencies [[ch.qos.logback/logback-classic "1.2.3"] + [metrics-clojure "2.10.0" :exclusions [org.clojure/clojure]]]}} :deploy-repositories [["releases" {:url "https://clojars.org/repo/" :creds :gpg}]] diff --git a/src/troy_west/cronut.clj b/src/troy_west/cronut.clj index 7f73d6b..7280d2f 100644 --- a/src/troy_west/cronut.clj +++ b/src/troy_west/cronut.clj @@ -67,23 +67,27 @@ (.withSchedule ^TriggerBuilder (base-trigger-builder config) (cron-schedule config))) -(defrecord ProxyJob [proxied-job] +(defn default-proxy-fn + [job job-context] + (try + (.execute ^Job job job-context) + (catch JobExecutionException ex + (throw ex)) + (catch Exception ex + (throw (JobExecutionException. ^Exception ex))))) + +(defrecord ProxyJob [proxied-job proxy-fn] Job (execute [_ job-context] - (try - (.execute ^Job proxied-job job-context) - (catch JobExecutionException ex - (throw ex)) - (catch Exception ex - (throw (JobExecutionException. ^Exception ex)))))) + (proxy-fn proxied-job job-context))) (defn job-factory - [scheduled] + [scheduled proxy-fn] (reify JobFactory (newJob [_ bundle _] (let [job-detail (.getJobDetail ^TriggerFiredBundle bundle) job-key (.getKey job-detail)] - (->ProxyJob (get scheduled job-key)))))) + (->ProxyJob (get scheduled job-key) proxy-fn))))) (defn proxy [job] @@ -95,7 +99,7 @@ (boolean? durable?) (.storeDurably durable?))))) (defn activate - [^Scheduler scheduler schedule] + [^Scheduler scheduler schedule proxy-fn] (.clear scheduler) (loop [schedule schedule scheduled {} @@ -111,13 +115,13 @@ (log/info "scheduling new job" trigger proxy-detail) (.scheduleJob scheduler proxy-detail (.build trigger)) (recur (rest schedule) (assoc scheduled job-key job) (assoc proxies job proxy-detail)))) - (.setJobFactory scheduler (job-factory scheduled)))) + (.setJobFactory scheduler (job-factory scheduled (or proxy-fn default-proxy-fn))))) (.start scheduler) scheduler) (defn initialize [config] - (let [{:keys [schedule time-zone update-check?]} config] + (let [{:keys [schedule proxy-fn time-zone update-check?]} config] (log/infof "initializing schedule of [%s] jobs" (count schedule)) (when time-zone (log/infof "with default time-zone %s" time-zone) @@ -125,7 +129,7 @@ (when-not update-check? (System/setProperty "org.terracotta.quartz.skipUpdateCheck" "true") (log/infof "with quartz update check disabled" time-zone)) - (activate (StdSchedulerFactory/getDefaultScheduler) schedule))) + (activate (StdSchedulerFactory/getDefaultScheduler) schedule proxy-fn))) (defn shortcut-interval "Trigger immediately, at an interval-ms, run forever (well that's optimistic but you get the idea)" diff --git a/test-resources/config.edn b/test-resources/config.edn index 650c60b..0708b98 100644 --- a/test-resources/config.edn +++ b/test-resources/config.edn @@ -1,52 +1,57 @@ -{:dep/one {:a 1} - - :test.job/one {:dep-one #ig/ref :dep/one} - - :test.job/two {:identity ["job-two" "test"] - :description "test job" - :recover? true - :durable? false - :dep-one #ig/ref :dep/one - :dep-two #ig/ref :test.job/one} - - :cronut/scheduler {:time-zone "Australia/Melbourne" - :schedule [;; basic interval - {:job #ig/ref :test.job/one - :trigger #cronut/trigger {:type :simple - :interval 2 - :time-unit :seconds - :repeat :forever}} - - ;; full interval - {:job #ig/ref :test.job/two - :trigger #cronut/trigger {:type :simple - :interval 3000 - :repeat :forever - :identity ["trigger-two" "test"] - :description "test trigger" - :start #inst "2019-01-01T00:00:00.000-00:00" - :end #inst "2019-02-01T00:00:00.000-00:00" - :priority 5}} - - ;; shortcut interval - {:job #ig/ref :test.job/two - :trigger #cronut/interval 3500} - - ;; basic cron - {:job #ig/ref :test.job/two - :trigger #cronut/trigger {:type :cron - :cron "*/4 * * * * ?"}} - - ;; full cron - {:job #ig/ref :test.job/two - :trigger #cronut/trigger {:type :cron - :cron "*/6 * * * * ?" - :identity ["trigger-five" "test"] - :description "another-test trigger" - :start #inst "2018-01-01T00:00:00.000-00:00" - :end #inst "2029-02-01T00:00:00.000-00:00" - :priority 4}} - - ;; shortcut cron - {:job #ig/ref :test.job/two - :trigger #cronut/cron "*/8 * * * * ?"}]}} \ No newline at end of file +{:dep/one {:a 1} + + :test.job/one {:dep-one #ig/ref :dep/one} + + :test.job/two {:identity ["job-two" "test"] + :description "test job" + :recover? true + :durable? false + :dep-one #ig/ref :dep/one + :dep-two #ig/ref :test.job/one} + + :metric/registry {} + + :scheduler/proxy-fn {:registry #ig/ref :metrics/registry} + + :cronut/scheduler {:time-zone "Australia/Melbourne" + :proxy-fn #ig/ref :scheduler/proxy-fn + :schedule [;; basic interval + {:job #ig/ref :test.job/one + :trigger #cronut/trigger {:type :simple + :interval 2 + :time-unit :seconds + :repeat :forever}} + + ;; full interval + {:job #ig/ref :test.job/two + :trigger #cronut/trigger {:type :simple + :interval 3000 + :repeat :forever + :identity ["trigger-two" "test"] + :description "test trigger" + :start #inst "2019-01-01T00:00:00.000-00:00" + :end #inst "2019-02-01T00:00:00.000-00:00" + :priority 5}} + + ;; shortcut interval + {:job #ig/ref :test.job/two + :trigger #cronut/interval 3500} + + ;; basic cron + {:job #ig/ref :test.job/two + :trigger #cronut/trigger {:type :cron + :cron "*/4 * * * * ?"}} + + ;; full cron + {:job #ig/ref :test.job/two + :trigger #cronut/trigger {:type :cron + :cron "*/6 * * * * ?" + :identity ["trigger-five" "test"] + :description "another-test trigger" + :start #inst "2018-01-01T00:00:00.000-00:00" + :end #inst "2029-02-01T00:00:00.000-00:00" + :priority 4}} + + ;; shortcut cron + {:job #ig/ref :test.job/two + :trigger #cronut/cron "*/8 * * * * ?"}]}} \ No newline at end of file diff --git a/test/troy_west/cronut/integration_fixture.clj b/test/troy_west/cronut/integration_fixture.clj index df475d0..9ba1dd2 100644 --- a/test/troy_west/cronut/integration_fixture.clj +++ b/test/troy_west/cronut/integration_fixture.clj @@ -3,8 +3,10 @@ [clojure.java.io :as io] [troy-west.cronut :as cronut] [integrant.core :as ig] + [metrics.core :as metrics] + [metrics.meters :as meters] [clojure.tools.logging :as log]) - (:import (org.quartz Job))) + (:import (org.quartz Job JobExecutionException))) (defonce system (atom {})) @@ -27,6 +29,20 @@ [_ config] (map->TestDefrecordJobImpl config)) +(defmethod ig/init-key :tmetric/registry + [_ config] + (metrics/new-registry)) + +(defmethod ig/init-key :scheduler/proxy-fn + [_ config] + (let [registry (:metric/registry config)] + (fn [job job-context] + (try + (meters/mark! (meters/meter "")) + (.execute ^Job job job-context) + (catch Exception ex + (throw (JobExecutionException. ^Exception ex))))))) + (defn initialize! [] (reset! system (cronut/init-system (slurp (io/resource "config.edn")))))