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
Using 100s of routes with ring async handlers causes StackOverflowError #187
Comments
An idea (though not bullet proof), we could make (defn routes
"Create a Ring handler by combining several handlers into one."
[& handlers]
(fn
([request]
(apply compojure/routing request handlers))
([request respond raise]
(letfn [(f [handlers]
(loop [[handler & remaining-handlers] handlers]
(if handler
(let [respond' #(if % (respond %) (f remaining-handlers))]
(when (= (handler request respond' raise) ::compojure/no-route-found)
(recur remaining-handlers)))
(respond nil))))]
(f handlers))))) It can technically still run into the same issues if lots of routes match though the chances are slim. |
That's an interesting problem. As a temporary workaround, I'd suggest increasing the stack size for the running JVM, since you're not dealing with an unbounded stack. Solving the problem in a more general way will require a bit of thought. |
We have a large ring/compojure application with lots of api routes. We are trying to use ring's async handlers but we eventually run out of stack if a matching path is not found in time.
This is fine because it matches a route soon enough
The issue is that it will create a new entry in the stack for each handler that doesn't match:
Even if you break it into chunks like so, you still get the same error.
This can be rewritten using something like a go loop, but it's possible code is blocking and may unknowingly block peoples core async threads.
Any suggestions?
The text was updated successfully, but these errors were encountered: