Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interceptor compile gets called too many times #308

Closed
kennyjwilli opened this issue Aug 27, 2019 · 1 comment
Closed

Interceptor compile gets called too many times #308

kennyjwilli opened this issue Aug 27, 2019 · 1 comment

Comments

@kennyjwilli
Copy link

kennyjwilli commented Aug 27, 2019

I added a println to my interceptor's :compile function and it prints 4 times when I expected it to print 2 times.

Example code:

(ns compute.http-api.example
  (:require
    [clojure.spec.alpha :as s]
    [reitit.http :as http]
    [reitit.ring :as ring]
    [reitit.http.spec :as spec]
    [reitit.interceptor.sieppari :as sieppari]
    [spec-tools.spell :as spell]))

(s/def ::session-interceptor
  (s/keys :opt-un [::session]))

(def routes
  [["/ping" {:session {}
             :get     (fn [ctx]
                        (prn "ping")
                        {:status  200
                         :body    "pong2"
                         :headers {}})}]])

(def session-interceptor
  {:name    ::session
   :spec    ::session-interceptor
   :compile (fn [{:keys [session]} _]
              (prn "here")
              (when session
                {:enter (fn session-interceptor-enter [ctx]
                          (println "enter")
                          ctx)
                 :leave (fn session-interceptor-leave [ctx]
                          (println "leave")
                          ctx)}))})

(def app
  (http/ring-handler
    (http/router
      routes
      {:data             {:interceptors [session-interceptor]}
       :reitit.spec/wrap spell/closed
       :validate         spec/validate})
    (ring/create-default-handler)
    {:executor sieppari/executor}))

The output when loading this namespace is:

Loading src/compute/http_api/example.clj... 
"here"
"here"
"here"
"here"
Loaded

From the compile routes, it looks like there are only the two routes: one :get that I defined and one generated :options.

[["/ping"
  {:interceptors [{:name :compute.http-api.example/session,
                   :spec :compute.http-api.example/session-interceptor,
                   :compile #object[compute.http_api.example$fn__19986
                                    0x161124a7
                                    "compute.http_api.example$fn__19986@161124a7"]}],
   :session {:store "asd"},
   :get {:handler #object[compute.http_api.example$fn__19983 0x17267d23 "compute.http_api.example$fn__19983@17267d23"]}}
  #reitit.ring.Methods{:get #reitit.http.Endpoint{:data {:interceptors [{:name :compute.http-api.example/session,
                                                                         :spec :compute.http-api.example/session-interceptor,
                                                                         :compile #object[compute.http_api.example$fn__19986
                                                                                          0x161124a7
                                                                                          "compute.http_api.example$fn__19986@161124a7"]}],
                                                         :session {:store "asd"},
                                                         :handler #object[compute.http_api.example$fn__19983
                                                                          0x17267d23
                                                                          "compute.http_api.example$fn__19983@17267d23"]},
                                                  :interceptors [#reitit.interceptor.Interceptor{:name :compute.http-api.example/session,
                                                                                                 :enter #object[compute.http_api.example$fn__19986$session_interceptor_enter__19988
                                                                                                                0x61f75747
                                                                                                                "compute.http_api.example$fn__19986$session_interceptor_enter__19988@61f75747"],
                                                                                                 :leave #object[compute.http_api.example$fn__19986$session_interceptor_leave__19990
                                                                                                                0x2c9a9ac0
                                                                                                                "compute.http_api.example$fn__19986$session_interceptor_leave__19990@2c9a9ac0"],
                                                                                                 :error nil,
                                                                                                 :spec :compute.http-api.example/session-interceptor}
                                                                 #reitit.interceptor.Interceptor{:name :reitit.interceptor/handler,
                                                                                                 :enter #object[reitit.interceptor$eval4369$fn__4370$fn__4371
                                                                                                                0x33b1b7e8
                                                                                                                "reitit.interceptor$eval4369$fn__4370$fn__4371@33b1b7e8"],
                                                                                                 :leave nil,
                                                                                                 :error nil,
                                                                                                 :reitit.interceptor/handler #object[compute.http_api.example$fn__19983
                                                                                                                                     0x17267d23
                                                                                                                                     "compute.http_api.example$fn__19983@17267d23"]}],
                                                  :queue #object[clojure.lang.PersistentQueue
                                                                 0x4d0b5502
                                                                 "clojure.lang.PersistentQueue@66c34d0d"],
                                                  :handler nil,
                                                  :path "/ping",
                                                  :method :get},
                       :head nil,
                       :post nil,
                       :put nil,
                       :delete nil,
                       :connect nil,
                       :options #reitit.http.Endpoint{:data {:interceptors [{:name :compute.http-api.example/session,
                                                                             :spec :compute.http-api.example/session-interceptor,
                                                                             :compile #object[compute.http_api.example$fn__19986
                                                                                              0x161124a7
                                                                                              "compute.http_api.example$fn__19986@161124a7"]}],
                                                             :session {:store "asd"},
                                                             :no-doc true,
                                                             :handler #object[reitit.ring$fn__4906$fn__4915
                                                                              0x60b23b5b
                                                                              "reitit.ring$fn__4906$fn__4915@60b23b5b"]},
                                                      :interceptors [#reitit.interceptor.Interceptor{:name :compute.http-api.example/session,
                                                                                                     :enter #object[compute.http_api.example$fn__19986$session_interceptor_enter__19988
                                                                                                                    0x131f5d21
                                                                                                                    "compute.http_api.example$fn__19986$session_interceptor_enter__19988@131f5d21"],
                                                                                                     :leave #object[compute.http_api.example$fn__19986$session_interceptor_leave__19990
                                                                                                                    0x59471641
                                                                                                                    "compute.http_api.example$fn__19986$session_interceptor_leave__19990@59471641"],
                                                                                                     :error nil,
                                                                                                     :spec :compute.http-api.example/session-interceptor}
                                                                     #reitit.interceptor.Interceptor{:name :reitit.interceptor/handler,
                                                                                                     :enter #object[reitit.interceptor$eval4369$fn__4370$fn__4371
                                                                                                                    0x4e73eb2e
                                                                                                                    "reitit.interceptor$eval4369$fn__4370$fn__4371@4e73eb2e"],
                                                                                                     :leave nil,
                                                                                                     :error nil,
                                                                                                     :reitit.interceptor/handler #object[reitit.ring$fn__4906$fn__4915
                                                                                                                                         0x60b23b5b
                                                                                                                                         "reitit.ring$fn__4906$fn__4915@60b23b5b"]}],
                                                      :queue #object[clojure.lang.PersistentQueue
                                                                     0x56f5cdc1
                                                                     "clojure.lang.PersistentQueue@1aee94c2"],
                                                      :handler nil,
                                                      :path "/ping",
                                                      :method :options},
                       :trace nil,
                       :patch nil}]]
@ikitommi
Copy link
Member

ikitommi commented Sep 9, 2019

Hi. The interceptors are first compiled on reitit.http/router creation and second on reitit.http/ring-handler, which effectively doubles the compile times. This is needed as the ring-handler adds new route data &/ router options like the top-level interceptors and info about the executor - the interceptors COULD use this added data at compile-time to compile differently.

I think this is inconvenient, but does not effect runtime performance and should not matter a lot when creating a router.

If you think differently, please reopen and let's see if/how this could be changed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants