In web apps for Python, if you change the source, you can immediately see the difference in your web app. Can this be done with Nim and Jester?
I read about hot reloading, but it requires that your main module calls another module that can be reloaded. But how to do this with Jester? From what I can tell there is no proc for the web app for a main module to call.
I haven't used Jester before, but the custom router example shows how to get a proc: https://github.com/dom96/jester#custom-router
Additionally, I took a quick scan of the code and routes: is a macro, so it's just dumping a bunch of code at the top level, try putting the routes: block in a proc and calling it?
because macros are slow to compile, and Jester relies heavily on macros.
The macros which Jester uses are incredibly light. You're very unlikely to see a slowdown of compilation because of them. You can also avoid them completely if you really want to, see https://github.com/dom96/jester/blob/master/tests/example2.nim
I'm trying to use the example2.nim as a guide, but while the resp macro works, the redirect macro fails to compile:
../my_program/routes.nim(179, 20) template/generic instantiation of `redirect` from here
/Users/user/.nimble/pkgs/jester-0.5.0/jester.nim(592, 11) Error: undeclared identifier: 'allRoutes'
Do you know how can I fix this?
I think flask simply restarts when a file is changed, so it should be enough to have a wrapper script with fswatch or similar that auto-restarts your executable.
It makes sense to do it that way because you are guaranteed to get the correct code whether your reload was automatic or manual- no subtle bugs.
If startup time is an issue I'd optimize that before I'd hot reload in my test cycle.
Having said that, hot reloading is cool, I'd just fibd a different use case to work with it, like a plugin architecture.
If you want to get really fancy with reloading you could detect which nim files are included and only watch those, but that's as far as I'd take it because KISS.
Recompilation will fail because the binary is in use. So, kill first, then recompile and run.
Killing the process might be tricky on posix since you'd need to get the PID by binary name first but it's doable. On Windows it's easier with ps app.exe | kill.
I just thought there was an easier way.
Anyway, thanks for the reply!
I am trying using osproc to reload but I can't seem to get stdout from server.exe. I'd like to be able to see the debug msg from jester.
import std/osproc
import std/os
import std/tables
import std/times
import std/strutils
discard execCmd("nim c server.nim")
var p = startProcess("server.exe", options={poUsePath,poStdErrToStdOut})
proc atExit() {.noconv.} =
p.terminate()
p.close()
quit(0)
setControlCHook(atExit)
var files: Table[string, Time] = {"path": getLastModificationTime(".")}.toTable
while true:
sleep(300)
for path in walkDirRec("."):
if ".git" in path:
continue
var (_, _, ext) = splitFile(path)
if ext in [".scss", ".sass", ".less", ".styl", ".pcss", ".postcss",".exe",".db"]:
continue
if files.hasKey(path):
if files[path] != getLastModificationTime(path):
echo("File changed: " & path)
p.terminate()
p.close()
echo "Terminating Server... Rebuilding"
echo execCmd("nim c server.nim")
p = startProcess("server.exe", options={poUsePath,poStdErrToStdOut})
files[path] = getLastModificationTime(path)
else:
if absolutePath(path) in [absolutePath("runserver.nim")]:
continue
files[path] = getLastModificationTime(path)