This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-09-11
Channels
- # announcements (18)
- # beginners (57)
- # calva (20)
- # cider (4)
- # cljdoc (15)
- # cljs-dev (14)
- # clojure (124)
- # clojure-europe (5)
- # clojure-italy (5)
- # clojure-nl (10)
- # clojure-spec (4)
- # clojure-uk (44)
- # clojurescript (4)
- # clojutre (18)
- # clr (2)
- # cursive (25)
- # datomic (53)
- # emacs (18)
- # events (1)
- # figwheel-main (1)
- # fulcro (34)
- # joker (6)
- # kaocha (13)
- # nrepl (3)
- # nyc (24)
- # off-topic (1)
- # pathom (16)
- # protorepl (4)
- # re-frame (1)
- # reitit (27)
- # rewrite-clj (5)
- # shadow-cljs (38)
- # spacemacs (25)
- # sql (20)
- # vim (28)
- # xtdb (20)
Hello, I have a problem with a coercion. I have a following route
(def routes
["/branch"
["/:branch-id" {:parameters {:path {:branch-id ::specs/id}}
:coercion reitit.coercion.spec/coercion}
subbranch-routes]])
(def a (atom {}))
(def subbranch-routes
["/subbranch" {}
["/say-hello" (fn [request] (reset a request) (response/ok "Hello"))
{:post {:handler
:responses {200 ::specs/response}}}]])
After performing request to /branch/1/subbranch/say-hello
I’ve found following in a
(-> @a first :path-params)
{:branch-id "1"}
but I expected
{:branch-id 1}
Could someone help me with this?
PS: I used following middlewares for coercion
coercion/coerce-exceptions-middleware
coercion/coerce-request-middleware
coercion/coerce-response-middleware
@bohdan.mikhail the coerced parameters are written under :parameters
, so (-> @a first :parameters :path)
should do it
I recommend inspecting the request with https://cljdoc.org/d/metosin/reitit/0.3.9/doc/ring/transforming-middleware-chain#printing-request-diffs
Thanks! For some reason, coercion doesn’t work at all. If I use interceptors and middlewares at the same time which one will run first?
middleware & interceptors are not compatible. You should pick one. The request differs shows which mw/int are run and how they modify the request.
Is there will be some warning or so if you trying to use both at the same time? It will be very helpful.
you can turn on the spec validation for route data and use closed specs, will error on undefined keys
There are example projects to play with, e.g. https://github.com/metosin/reitit/blob/master/examples/ring-spec-swagger/src/example/server.clj#L79-L81
I believe Pedestal has something for that. Sieppari doesn't and most likely, never will. Mixing thread-local bindings with potentially async code is not a good idea, IMO.
Hmm. Previously we would have a map of key-values that would get included in all log messages by binding
in a top-level middleware. Is there an alternative with Reitit? For example, when a request comes in, tag it with a Request-ID and all log messages after that will include the request-id in the their message.
I could do something like this:
(def mdc (proxy [ThreadLocal] []
(initialValue []
(atom {}))))
That assumes the 1 thread per request model though. I assume if you use core.async, it is no longer 1 thread per request.Logback's MDC is also thread local: https://logback.qos.ch/manual/mdc.html. How does returning a core.async channel as a response fit into this?
Pedestal1 stores the bindings in a request map and it works with core.async too. So if you need that, you could use reitit-pedestal
instead of reitit-sieppari
, see http://pedestal.io/reference/context-map#_description
It is handy, but meant for single-threaded environments. To be pure, you could just put the raw info into context and have a context-logger that takes the context as argument and reads those from there.
In an ideal world, that's how it would work. We need to interop with Java libs that support MDC contexts. Further, I don't want to pass a whole context map to every single function that wants to log something, that's simply not scalable.
Is there a known cause for Reitit memory consumption to continually increase when serving large maps? Curious if I'm configuring it wrong.
In my application, if the :body
key is a map and there's a client continuously polling that endpoint, memory consumption will increase until an OOM. However, if I convert the map to a JSON string myself, this doesn't happen. (These maps are quite large.)
Here's an example
In this example, the left side of the screen is being polled without manually converting the body to a JSON string, and the right side of the screen is converting the body to a JSON string with clojure.data.json
.
(In the middle of the screen, the client has stopped polling.)
One thing I am doing is customizing the way JSON is decoded:
(def m
(muuntaja.core/create
(assoc-in muuntaja.core/default-options
[:formats "application/json" :decoder-opts]
{:decode-key-fn identity})))
Then I'm using m
in ring-router
. Something like this:
(ring-router
... routes here
{:data {:muuntaja m
...}})
I think that's the only non-standard thing I'm doing.what web server are you using? if that supports byte-arrays, you could try assoccing :return :bytes
to muuntaja config.
@ikitommi I'm using Aleph 0.4.7-alpha5. I'll see if I can get a repro together.
Also, this isn't urgent from my perspective. I know things are probably busy with ClojuTRE coming up, and I'm able to prevent the OOM errors by converting to a JSON string myself.
Here's a small repro of the memory leak: https://github.com/thomascothran/memory-leak-repro
(Haven't tried the :return :bytes
suggestion yet)
If I set :return
to :bytes
in the Muuntaja config, I don't get the memory leak. Thanks for that pointer @ikitommi
Here's a small repro of the memory leak: https://github.com/thomascothran/memory-leak-repro
(Haven't tried the :return :bytes
suggestion yet)
If I set :return
to :bytes
in the Muuntaja config, I don't get the memory leak. Thanks for that pointer @ikitommi