Skip to content

Commit

Permalink
Add :bindings support
Browse files Browse the repository at this point in the history
This is largely a port of @bnert's PR for sieppari

ref: metosin/sieppari#55

The caveats from that PR regarding a small hit to performance, probably
apply, though I did not do any benchmarking since the repo isn't setup
for it.
  • Loading branch information
Ramblurr committed Nov 13, 2024
1 parent a8ec8b7 commit 88c2d98
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 4 deletions.
14 changes: 11 additions & 3 deletions src/exoscale/interceptor/impl.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,17 @@
[ctx interceptor stage err]
(if-let [f (get interceptor stage)]
(try
(let [ctx' (if err
(f (dissoc ctx :exoscale.interceptor/error) err)
(f ctx))]
(let [ctx' #?(:clj (with-bindings (or (:bindings ctx) {})
;; Given the various async
;; executors may exec on different threads,
;; the fn must be bound in order to preserve
;; bindings
(if err
((bound-fn* f) (dissoc ctx :exoscale.interceptor/error) err)
((bound-fn* f) ctx)))
:cljs (if err
(f (dissoc ctx :exoscale.interceptor/error) err)
(f ctx)))]
(cond-> ctx'
(p/async? ctx')
(p/catch (fn [e] (assoc ctx :exoscale.interceptor/error e)))))
Expand Down
13 changes: 13 additions & 0 deletions test/exoscale/interceptor/manifold_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -159,3 +159,16 @@
;; just to make sure we preserve chaining
{:enter (fn [ctx] (assoc ctx :g 7))}])
(select-keys [:a :b :c :d :e :f :g])))))

(def ^:dynamic *boundv* 41)
(def bindings-result {:result 43})

(deftest manifold-bindings-test
(let [bindings-chain [{:enter (fn [ctx] (d/future (assoc ctx :bindings {#'*boundv* 42})))}
{:enter #(d/success-deferred (update-in % [:bindings #'*boundv*] inc))}
#(d/success-deferred (assoc % :result *boundv*))]]

(is (= bindings-result
(-> (ixm/execute {} bindings-chain)
deref
clean-ctx)))))
34 changes: 33 additions & 1 deletion test/exoscale/interceptor_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

(defn clean-ctx
[ctx]
(dissoc ctx ::ix/queue ::ix/stack))
(dissoc ctx ::ix/queue ::ix/stack :bindings))

(deftest a-test-workflow
(is (= default-result
Expand Down Expand Up @@ -256,3 +256,35 @@
:leave (fn [ctx] (q/error-future ex))}]
(is (thrown? Exception @(ixq/execute start-ctx
[dinc])))))

(def ^:dynamic *boundv* 41)
(def bindings-result {:result 43})

(deftest use-bindings-test
;; bindings are conveyed across interceptor chain
(let [bindings-chain [{:enter #(assoc % :bindings {#'*boundv* 42})}
{:enter (fn [ctx] (is (= 42 *boundv*)) ctx)}
{:enter #(update-in % [:bindings #'*boundv*] inc)}
#(assoc % :result *boundv*)]]

(is (= bindings-result (-> (ix/execute {} bindings-chain)
clean-ctx)))))

(deftest core-async-bindings-test
(let [bindings-chain [{:enter #(a/go (assoc % :bindings {#'*boundv* 42}))}
{:enter #(a/go (update-in % [:bindings #'*boundv*] inc))
:leave #(a/go (update-in % [:bindings #'*boundv*] dec))}
#(a/go (assoc % :result *boundv*))]]

(is (= bindings-result (-> (ixa/execute {} bindings-chain)
a/<!!
clean-ctx)))))

(deftest auspex-bindings-test
(let [bindings-chain [{:enter (fn [ctx] (q/future (fn [] (assoc ctx :bindings {#'*boundv* 42}))))}
{:enter #(q/success-future (update-in % [:bindings #'*boundv*] inc))}
#(q/success-future (assoc % :result *boundv*))]]

(is (= bindings-result (-> (ixq/execute {} bindings-chain)
deref
clean-ctx)))))

0 comments on commit 88c2d98

Please sign in to comment.