0
Fork 0
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:
Andrey Antukh 2020-02-05 23:49:26 +01:00
parent cd8a907a86
commit 1ac6e466ce
9 changed files with 82 additions and 76 deletions

View file

@ -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]

View file

@ -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))

View file

@ -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

View file

@ -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))))

View file

@ -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]

View file

@ -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)))

View file

@ -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)

View file

@ -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))))

View file

@ -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)