Is there a way to make HttpServer more robust?
Like if too many connections opened it should fail but maybe somehow find oldest unused connection and close it, or refuse the new connection or something like that? Currently it would fail.
import os, asyncdispatch, asynchttpserver, httpclient, httpcore
proc run_server =
proc handler(req: Request): Future[void] {.gcsafe.} =
return req.respond(Http200, "ok")
var server = new_async_http_server()
async_check server.serve(Port(4000), handler, "localhost")
run_forever()
proc run_client =
for _ in 1..1000:
let client = new_http_client()
echo client.post_content("http://localhost:4000/db/test", "ask")
case param_str(1)
of "server": run_server()
of "client": run_client()
else:
echo "wrong command"
quit(1)
Run client and server nim c -r script.nim server and nim c -r script.nim client and the server would fail with the error:
Error: unhandled exception: Too many open files
Async traceback:
/alex/projects/nim/play.nim(18) play
/alex/projects/nim/play.nim(10) run_server
/balex/applications/nim-1.4.2/lib/pure/asyncdispatch.nim(1930) runForever
/balex/applications/nim-1.4.2/lib/pure/asyncdispatch.nim(1627) poll
/balex/applications/nim-1.4.2/lib/pure/asyncdispatch.nim(1368) runOnce
/balex/applications/nim-1.4.2/lib/pure/asyncdispatch.nim(208) processPendingCallbacks
/balex/applications/nim-1.4.2/lib/pure/asyncmacro.nim(29) serveNimAsyncContinue
/balex/applications/nim-1.4.2/lib/pure/asyncmacro.nim(145) serveIter
/balex/applications/nim-1.4.2/lib/pure/asyncfutures.nim(372) read
Exception message: Too many open files
Exception type: [OSError]
you're probably hitting user limit for your operating system
if linux base, what's the output of
$ ulimit -n
?But shouldn't the server be robust and don't fail?
Like it could refuse to take new connection, or maybe drop old, but not crash.
If assumedDescriptorsPerRequest is 0 or greater the server cares about the process's maximum file descriptor limit. It then ensures that the process still has the resources for assumedDescriptorsPerRequest file descriptors before accepting a connection.
That is, use
async_check server.serve(Port(4000), handler, "localhost", 5)