All examples I've seen consider that we start Jester on the top level of a module. How can I start (and eventually stop) Jester inside a proc?
For example, I would like to be able to do something like this:
import jester, asyncdispatch, htmlgen, strutils
proc web() {.thread.} =
echo "Starting Web interface..."
var total : int = 10
routes:
get "/" :
resp h1("Hello world")
get "/num" :
resp h2(intToStr(total))
runForever()
when isMainModule:
var thrWeb : TThread[void]
echo "Starting web thread"
createThread[void](thrWeb, web)
while(true) :
sleep(2000)
This code does not build with a strange error:
error: passing 'TY237205' to parameter of incompatible type 'TY234892' (aka 'FutureHEX3Aobjecttype233048 *(*)(RequestHEX3Aobjecttype233062 *, ResponseHEX3Aobjecttype233081 *)')
serve_234890(LOC3, settings);
note: passing argument to parameter 'match' here
N_NIMCALL(void, serve_234890)(TY234892 match, SettingsHEX3Aobjecttype233053* settings);
And is there any way to stop Jester without killing the whole thread? So it can be started and stopped by a signal from another thread...
I am doing something like this (excerpt from my code). The logPath is used to change jesters default logging location. I omitted that in the snippet below.
import jester, asyncdispatch, asyncnet, htmlgen
var
workerThread: Thread[tuple[logPath: string]]
workerChannel: Channel[tuple[terminate: bool]]
proc terminate() =
workerChannel.send((terminate: true))
proc match(request: Request, response: Response): Future[bool] {.async.} =
result = true
case request.reqMeth
of HttpGet:
case request.pathInfo
of "/":
await response.sendHeaders()
await response.send("Hello World!")
else: discard
else: discard
response.client.close()
proc workerRun(params: tuple[logPath: string]) {.thread.} =
jester.serve(match)
while true:
poll()
let res = workerChannel.tryRecv()
if res.dataAvailable:
if res.msg.terminate:
break
proc startWorker*(logPath: string) =
workerChannel.open()
createThread(workerThread, workerRun, (logPath: logPath))
proc stopWorker*() =
terminate()
joinThread(workerThread)
workerChannel.close()
In general, it is not a given that HTTP communication is the main focus of an application. One may very well have the need to expose some functionality of an application over HTTP, while at the same time handling other protocols or doing other things.
I find it a very big plus when I am in control of when and how to serve HTTP content, instead of living in a framework.
singularity, Thanks for this example, I've found this way too, but I hoped to have something more simple, without needing to redefine match function. It seems that there is no such possibility.
dom96, As it was already mentioned by andrea, the web interface is definitely not the main thing my application do. So I prefer isolate it in separate thread, if this thread has some problem - another threads are still OK. Even more, I would like to stop web interface in some conditions.
Well as long as it works then I'm happy. I tend to avoid threads as much as I can though.
So I prefer isolate it in separate thread, if this thread has some problem - another threads are still OK. Even more, I would like to stop web interface in some conditions.
What do you mean by problem? Like if the thread crashes? I hope you are aware that if one of your threads crashes that your whole application goes down with it.