server.jl starts a HTTP server on 8080 for handling GET / POST requests.
I make some changes to server.jl (add/del a route) save the file, then the bash script restarts the HTTP server. How would you achieve this with Revise.jl ?
There is an example in the Revise docs of the basic workflow for running some webserver with some assets with automatic reloading.
In my understanding (not tested this) the idea would be to have a main file that you don’t change, and this loads revise as well as the package/file that contains the code to start your server and runs the main entrypoint to the server in the way defined in the revise example workflow I linked. Now it should automatically update the julia runtime with any updated code/assets if they are monitored by revise, so you don’t need to restart the server on update.
entr(["file.js", "assets"], [MyWebCode]) do
build_webpages(args...)
end
This is about as useful as inotify / watch.
What can we do with this? If we use kill -9 + julia server.jl, it’s not much of a improvement; we’ve merely moved “watching” to julia.
If there is some other way here of killing+ restarting the http server when src/server.jl is changed, (which I think many are hinting at), please let me know how.
I was just answering the question of how I think this would be done with revise which is what I though you were asking for. I think this is what other people hinted at as well but I might be wrong.
What do you mean by other way of killing + restarting the app, why do you want more ways? If you are happy with your way go with it, otherwise give revise a try. Or are you looking for some functionality that neither of them provide? In that case I might have misunderstood exactly what you want and need a clearer explanation.
To me it seems like a cleaner approach to use revise compared to the bash kill+restart, it is not “just” moved to julia IMO, though having it all in julia is nice by itself.
It as well allows for not restarting the julia session since revise just injects any updates into the running session IIUC. This seems like it should be more efficient, though I have not tested any of this so I might be completely off.
As stated in Compile time: we can't find any impls for this multi dispatch fn? - #23 by tim.holy, I think you’re failing to understand that you don’t have to kill it just because src/server.jl changed. (IIUC, Scala can’t recompile code within the same session when the code changes. But Julia most definitely can.) If you’re using Revise, you can update the running session, and all you need to do is regenerate the web pages.
With Revise.jl, you don’t need to kill the Julia process, just refresh the webpage in your browser and you should see change taking effect. Let us know if it doesn’t work
@mkitti used includet that is include with a t at the end of it. You are using include without the t. That may be the reason you are not seeing what is expected.
Revise has 2 modes of operation, the default mode would identify changes and recompile stuff on demand when you actually run something, and the other mode (polling) is usually not recommended unless you’re on a network mounted system where “file change” is not an observable of filesystem.
You could try polling but in that case you have a fixed latency so to speak, depends on how often Revise check for changes
A different approach could be: set your response Hello world to a variable. Set up another route that loads the text from a file and assigns to that variable. This way, it isn’t always reading the text from a file, but there is a way to refresh the information.
Here is a Revise.entr-based solution that should avoid the need to enter anything in the REPL to trigger Revise (it can actually run without a REPL at all)
using HTTP
const HOST = "127.0.0.1"
const PORT = 8080
function do_8080(_::HTTP.Request)
local r = HTTP.Response(200, "Hello World 1");
return r;
end
function start_server()
server_task = @async try
println("Server Started!")
router_8080 = HTTP.Router();
HTTP.register!(router_8080, "GET", "/", do_8080)
HTTP.register!(router_8080, "GET", "**", do_8080)
HTTP.serve(router_8080, "127.0.0.1", 8080)
catch e
e === :stop || rethrow()
end
errormonitor(server_task)
end
function stop_server(task)
schedule(task, :stop, error=true)
wait(task)
end
#outer.jl
using Revise
includet("inner.jl")
server_task = Ref(start_server())
entr(["inner.jl"], [], postpone=true) do
stop_server(server_task[])
server_task[] = start_server()
end