mirror of
https://github.com/penpot/penpot.git
synced 2025-03-11 23:31:21 -05:00
♻️ Refactor dispatcher implementation.
Simplify code and probabluy improve performance.
This commit is contained in:
parent
cd8a907a86
commit
1ac6e466ce
9 changed files with 82 additions and 76 deletions
|
@ -12,11 +12,9 @@
|
|||
[uxbox.util.dispatcher :as uds]))
|
||||
|
||||
(uds/defservice handle
|
||||
{:dispatch-by ::type
|
||||
:interceptors [uds/spec-interceptor
|
||||
uds/wrap-errors
|
||||
#_logging-interceptor
|
||||
#_context-interceptor]})
|
||||
:dispatch-by ::type
|
||||
:wrap [uds/wrap-spec
|
||||
uds/wrap-error])
|
||||
|
||||
(defmacro defmutation
|
||||
[key & rest]
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
[uxbox.util.data :as data]
|
||||
[uxbox.util.uuid :as uuid]
|
||||
[uxbox.util.storage :as ust]
|
||||
[vertx.core :as vc]))
|
||||
[vertx.util :as vu]))
|
||||
|
||||
(def thumbnail-options
|
||||
{:width 800
|
||||
|
@ -142,7 +142,7 @@
|
|||
(ex/raise :type :validation
|
||||
:code :image-type-not-allowed
|
||||
:hint "Seems like you are uploading an invalid image."))
|
||||
(p/let [image-opts (vc/blocking (images/info (:path content)))
|
||||
(p/let [image-opts (vu/blocking (images/info (:path content)))
|
||||
image-path (persist-image-on-fs content)
|
||||
thumb-opts thumbnail-options
|
||||
thumb-path (persist-image-thumbnail-on-fs thumb-opts image-path)
|
||||
|
@ -179,13 +179,13 @@
|
|||
|
||||
(defn persist-image-on-fs
|
||||
[{:keys [name path] :as upload}]
|
||||
(vc/blocking
|
||||
(vu/blocking
|
||||
(let [filename (fs/name name)]
|
||||
(ust/save! media/media-storage filename path))))
|
||||
|
||||
(defn persist-image-thumbnail-on-fs
|
||||
[thumb-opts input-path]
|
||||
(vc/blocking
|
||||
(vu/blocking
|
||||
(let [input-path (ust/lookup media/media-storage input-path)
|
||||
thumb-data (images/generate-thumbnail input-path thumb-opts)
|
||||
[filename ext] (fs/split-ext (fs/name input-path))
|
||||
|
|
|
@ -30,7 +30,8 @@
|
|||
[uxbox.util.blob :as blob]
|
||||
[uxbox.util.storage :as ust]
|
||||
[uxbox.util.uuid :as uuid]
|
||||
[vertx.core :as vc]))
|
||||
[uxbox.util.time :as tm]
|
||||
[vertx.util :as vu]))
|
||||
|
||||
;; --- Helpers & Specs
|
||||
|
||||
|
@ -172,7 +173,7 @@
|
|||
(ex/raise :type :validation
|
||||
:code :image-type-not-allowed
|
||||
:hint "Seems like you are uploading an invalid image."))
|
||||
(vc/blocking
|
||||
(vu/blocking
|
||||
(let [thumb-opts {:width 256
|
||||
:height 256
|
||||
:quality 75
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
[uxbox.util.blob :as blob]
|
||||
[uxbox.util.uuid :as uuid]
|
||||
[uxbox.util.storage :as ust]
|
||||
[vertx.core :as vc]))
|
||||
[vertx.util :as vu]))
|
||||
|
||||
;; --- Helpers & Specs
|
||||
|
||||
|
@ -187,7 +187,7 @@
|
|||
:code :image-type-not-allowed
|
||||
:hint "Seems like you are uploading an invalid image."))
|
||||
|
||||
(p/let [image-opts (vc/blocking (images/info (:path content)))
|
||||
(p/let [image-opts (vu/blocking (images/info (:path content)))
|
||||
image-path (imgs/persist-image-on-fs content)
|
||||
thumb-opts imgs/thumbnail-options
|
||||
thumb-path (imgs/persist-image-thumbnail-on-fs thumb-opts image-path)
|
||||
|
@ -245,6 +245,6 @@
|
|||
|
||||
(defn- copy-image!
|
||||
[path]
|
||||
(vc/blocking
|
||||
(vu/blocking
|
||||
(let [image-path (ust/lookup media/media-storage path)]
|
||||
(ust/save! media/media-storage (fs/name image-path) image-path))))
|
||||
|
|
|
@ -9,11 +9,9 @@
|
|||
[uxbox.util.dispatcher :as uds]))
|
||||
|
||||
(uds/defservice handle
|
||||
{:dispatch-by ::type
|
||||
:interceptors [uds/spec-interceptor
|
||||
uds/wrap-errors
|
||||
#_logging-interceptor
|
||||
#_context-interceptor]})
|
||||
:dispatch-by ::type
|
||||
:wrap [uds/wrap-spec
|
||||
uds/wrap-error])
|
||||
|
||||
(defmacro defquery
|
||||
[key & rest]
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
(:require
|
||||
[clojure.tools.logging :as log]
|
||||
[cuerdas.core :as str]
|
||||
[vertx.core :as vc]
|
||||
[vertx.util :as vu]
|
||||
[uxbox.core :refer [system]]
|
||||
[uxbox.common.exceptions :as ex]
|
||||
[uxbox.util.uuid :as uuid]
|
||||
|
@ -36,5 +36,5 @@
|
|||
|
||||
(defn handle-on-context
|
||||
[p]
|
||||
(->> (vc/get-or-create-context system)
|
||||
(vc/handle-on-context p)))
|
||||
(->> (vu/current-context system)
|
||||
(vu/handle-on-context p)))
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
[clojure.tools.logging :as log]
|
||||
[cuerdas.core :as str]
|
||||
[postal.core :as postal]
|
||||
[vertx.core :as vc]
|
||||
[vertx.util :as vu]
|
||||
[promesa.core :as p]
|
||||
[uxbox.common.exceptions :as ex]
|
||||
[uxbox.config :as cfg]
|
||||
|
@ -49,7 +49,7 @@
|
|||
|
||||
(defn send-email
|
||||
[email]
|
||||
(vc/blocking
|
||||
(vu/blocking
|
||||
(let [config (get-smtp-config cfg/config)
|
||||
result (if (:enabled config)
|
||||
(postal/send-message config email)
|
||||
|
|
|
@ -21,47 +21,43 @@
|
|||
java.util.HashMap))
|
||||
|
||||
(definterface IDispatcher
|
||||
(^void add [key f metadata]))
|
||||
(^void add [key f]))
|
||||
|
||||
(deftype Dispatcher [reg attr interceptors]
|
||||
(defn- wrap-handler
|
||||
[items handler]
|
||||
(reduce #(%2 %1) handler items))
|
||||
|
||||
(deftype Dispatcher [reg attr wrap-fns]
|
||||
IDispatcher
|
||||
(add [this key f metadata]
|
||||
(.put ^Map reg key (MapEntry/create f metadata))
|
||||
this)
|
||||
(add [this key f]
|
||||
(let [f (wrap-handler wrap-fns f)]
|
||||
(.put ^Map reg key f)
|
||||
this))
|
||||
|
||||
clojure.lang.IDeref
|
||||
(deref [_]
|
||||
{:registry reg
|
||||
:attr attr
|
||||
:interceptors interceptors})
|
||||
:wrap-fns wrap-fns})
|
||||
|
||||
clojure.lang.IFn
|
||||
(invoke [_ params]
|
||||
(let [key (get params attr)
|
||||
entry (.get ^Map reg key)]
|
||||
(if (nil? entry)
|
||||
(p/rejected (ex/error :type :not-found
|
||||
:code :method-not-found
|
||||
:hint "No method found for the current request."))
|
||||
(let [f (.key ^MapEntry entry)
|
||||
m (.val ^MapEntry entry)
|
||||
d (p/deferred)]
|
||||
|
||||
(sp/execute (conj interceptors f)
|
||||
(with-meta params m)
|
||||
#(p/resolve! d %)
|
||||
#(p/reject! d %))
|
||||
d)))))
|
||||
f (.get ^Map reg key)]
|
||||
(when (nil? f)
|
||||
(ex/raise :type :not-found
|
||||
:code :method-not-found
|
||||
:hint "No method found for the current request."))
|
||||
(f params))))
|
||||
|
||||
(defn dispatcher?
|
||||
[v]
|
||||
(instance? IDispatcher v))
|
||||
|
||||
(defmacro defservice
|
||||
[sname {:keys [dispatch-by interceptors]}]
|
||||
`(defonce ~sname (Dispatcher. (HashMap.)
|
||||
~dispatch-by
|
||||
~interceptors)))
|
||||
[sname & {:keys [dispatch-by wrap]}]
|
||||
`(def ~sname (Dispatcher. (HashMap.) ~dispatch-by ~wrap)))
|
||||
|
||||
(defn parse-defmethod
|
||||
[args]
|
||||
(loop [r {}
|
||||
|
@ -94,40 +90,53 @@
|
|||
(assoc r :args v :body n)
|
||||
(throw (ex-info "missing arguments vector" {}))))))
|
||||
|
||||
(defn add-method
|
||||
[^Dispatcher dsp key f meta]
|
||||
(let [f (with-meta f meta)]
|
||||
(.add dsp key f)
|
||||
dsp))
|
||||
|
||||
(defmacro defmethod
|
||||
[& args]
|
||||
(let [{:keys [key meta sym args body]} (parse-defmethod args)
|
||||
f `(fn ~args ~@body)]
|
||||
`(do
|
||||
(s/assert dispatcher? ~sym)
|
||||
(.add ~(with-meta sym {:tag 'uxbox.util.dispatcher.IDispatcher})
|
||||
~key ~f ~meta)
|
||||
~sym)))
|
||||
(add-method ~sym ~key ~f ~meta))))
|
||||
|
||||
(def spec-interceptor
|
||||
"An interceptor that conforms the request with the user provided
|
||||
spec."
|
||||
{:enter (fn [{:keys [request] :as data}]
|
||||
(let [{:keys [spec]} (meta request)]
|
||||
(if-let [spec (s/get-spec spec)]
|
||||
(let [result (s/conform spec request)]
|
||||
(if (not= result ::s/invalid)
|
||||
(assoc data :request result)
|
||||
(let [data (s/explain-data spec request)]
|
||||
(ex/raise :type :validation
|
||||
:code :spec-validation
|
||||
:explain (with-out-str
|
||||
(expound/printer data))
|
||||
:data (::s/problems data)))))
|
||||
data)))})
|
||||
(defn wrap-spec
|
||||
[handler]
|
||||
(let [mdata (meta handler)
|
||||
spec (s/get-spec (:spec mdata))]
|
||||
(if (nil? spec)
|
||||
handler
|
||||
(with-meta
|
||||
(fn [params]
|
||||
(let [result (s/conform spec params)]
|
||||
(if (not= result ::s/invalid)
|
||||
(handler result)
|
||||
(let [data (s/explain-data spec params)]
|
||||
(ex/raise :type :validation
|
||||
:code :spec-validation
|
||||
:explain (with-out-str
|
||||
(expound/printer data))
|
||||
:data (::s/problems data))))))
|
||||
(assoc mdata ::wrap-spec true)))))
|
||||
|
||||
(def wrap-errors
|
||||
{:error
|
||||
(fn [data]
|
||||
(let [error (:error data)
|
||||
mdata (meta (:request data))]
|
||||
(assoc data :error (ex/error :type :service-error
|
||||
(defn wrap-error
|
||||
[handler]
|
||||
(let [mdata (meta handler)]
|
||||
(with-meta
|
||||
(fn [params]
|
||||
(try
|
||||
(-> (handler params)
|
||||
(p/catch' (fn [error]
|
||||
(ex/raise :type :service-error
|
||||
:name (:spec mdata)
|
||||
:cause error))))})
|
||||
|
||||
:cause error))))
|
||||
(catch Throwable error
|
||||
(p/rejected (ex/error :type :service-error
|
||||
:name (:spec mdata)
|
||||
:cause error)))))
|
||||
(assoc mdata ::wrap-error true))))
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
[uxbox.tests.helpers :as th]
|
||||
[uxbox.util.storage :as ust]
|
||||
[uxbox.util.uuid :as uuid]
|
||||
[vertx.core :as vc]))
|
||||
[vertx.util :as vu]))
|
||||
|
||||
(t/use-fixtures :once th/state-init)
|
||||
(t/use-fixtures :each th/database-reset)
|
||||
|
|
Loading…
Add table
Reference in a new issue