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