I’m trying to make use of
clojure.tools/namespace to be able to reload my very basic web service that I build with Pedestal… and obviously there’s something I don’t understand.
My goal was to be able to, start the server, test it, make some changes on the code, stop, refresh and start the server again to see my changes… and all this without having to restart the Repl. My problem is that applying this workflow doesn’t reflect the changes I made to the code and I can’t see why.
The project can be found here, and here is a summary to what I did:
deps.edn in a dedicated
- create a
./dev/user.clj at project root - in here I plan to put the code to start/stop and refresh. I’m also calling
(set-refresh-dirs "src") because I don’t whant
./dev to be reloaded
- start Repl (Im using Calva)
user.clj and then start the server.
(def srv (server/start))
At this point the server is started and everything seems fine.
- make some modification in the
/greet handler function and save
user.clj stop, refresh, and start the server again
(def srv (server/start))
The server is up, but
/greet returns the exact same response as before
Any help would be very appreciated …
Thanks in advance
You can have your changes take effect without restarting your server and without using
routes here: clojure-playground/play_3.clj at 28e7778aee2e598430f4c12bdb07744efb3213aa · raoul2000/clojure-playground · GitHub
:io.pedestal.http/routes in your service map is a function, pedestal evaluates it to get the routes each time a request comes into your service (if I understand correctly).
With that change in place, update your response in
respond-hello to something new, evaluate the
respond-hello function again in your repl, then hit your greet endpoint again and you’ll see the change. I tested this myself with your project.
Thanks for your reply @bpringe it works as expected…
…actually my goal also to understand how to use
tools.namespace. I still don’t get why calling
refresh didn’t reload the
/greet handler. There may be soms persistent stuff that is not refreshed … but what ? …
You’re welcome. I think what’s happening when you see the old version of the handler code running after you call
refresh is that it is reloading the play_3.clj, but the
user ns still refers to the old version of that namespace, referred in
server. So at that point, stopping the server and restarting it restarts the old version of the server, which uses the old version of the
After you run
refresh, if you try to load the
user ns, you’ll get an error that
server is already defined. You can fix that by running
(ns-unalias 'user 'server), then loading the user ns again. This loads the new version of the
play-3.play-3 ns, aliased as
server. After that you can start your server again and see the change reflected when you hit the greet handler.
I actually had the code update work a couple of times without the user ns load error mentioned above (I believe I stopped and started the server after calling
refresh and loading the user ns without error), but I think those times were only after just starting a new repl. I don’t know why it worked differently then.
Thanks again for this clear explanation…
I understand better this case now and more important I understand I need to study some more about namespaces in clojure (because obviously I’m not comfortable with them)
That I will do …
This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.