Skip to content

Commit

Permalink
Merge pull request #158 from daveray/hystrix-clj-expose-command-instance
Browse files Browse the repository at this point in the history
Expose current HystrixCommand to fns
  • Loading branch information
benjchristensen committed Jul 26, 2013
2 parents 4feab8a + d4f992a commit a911859
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,21 @@

;################################################################################

(def ^:dynamic *command*
"A dynamic var which is bound to the HystrixCommand instance during execution of
:run-fn and :fallback-fn.
It's occasionally useful, especially for fallbacks, to base the result on the state of
the comand. The fallback might vary based on whether it was triggered by an application
error versus a timeout.
Note: As always with dynamic vars be careful about scoping. This binding only holds for
the duration of the :run-fn or :fallback-fn.
"
nil)

;################################################################################

(defmacro with-request-context
"Executes body within a new Hystrix Context.
Expand Down Expand Up @@ -616,10 +631,14 @@
(when (not (instance? HystrixCommand$Setter setter))
(throw (IllegalStateException. (str ":init-fn didn't return HystrixCommand$Setter instance"))))
(proxy [HystrixCommand] [^HystrixCommand$Setter setter]
(run [] (apply run-fn args))
(getFallback [] (if fallback-fn
(apply fallback-fn args)
(throw (UnsupportedOperationException. "No :fallback-fn provided"))))
(run []
(binding [*command* this]
(apply run-fn args)))
(getFallback []
(if fallback-fn
(binding [*command* this]
(apply fallback-fn args))
(throw (UnsupportedOperationException. "No :fallback-fn provided"))))
(getCacheKey [] (if cache-key-fn
(apply cache-key-fn args))))))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,31 @@
(is (= "hello-world" (.get qc) @qc))
(is (.isDone qc))))))

(deftest test-this-command-binding
(let [base-def {:type :command
:group-key :test-this-command-binding-group
:command-key :test-this-command-binding
}]
(testing "this is bound while :run-fn is executing"
(let [captured (atom nil)
command-def (normalize (assoc base-def
:run-fn (fn []
(reset! captured *command*))))
command (instantiate command-def)]
(.execute command)
(is (identical? command @captured))))


(testing "this is bound while :fallback-fn is executing"
(let [captured (atom nil)
command-def (normalize (assoc base-def
:run-fn (fn [] (throw (Exception. "FALLBACK!")))
:fallback-fn (fn [] (reset! captured *command*))
))
command (instantiate command-def)]
(.execute command)
(is (identical? command @captured))))))

(deftest test-collapser
; These atoms are only for testing. In real life, collapser functions should *never*
; have side effects.
Expand Down

0 comments on commit a911859

Please sign in to comment.