Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for #18161 AsyncHttpServer Issue Too many open files. #18198

Closed
wants to merge 4 commits into from
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions lib/pure/asynchttpserver.nim
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@

import asyncnet, asyncdispatch, parseutils, uri, strutils
import httpcore
from times import DateTime, now, `-`, inSeconds

export httpcore except parseHeader

Expand Down Expand Up @@ -289,6 +290,9 @@ proc processRequest(
request.client.close()
return false

const
keepaliveTimeout* {.intdefine.} = 60 ### default value for keepaliveTimeout in seconds

mrhdias marked this conversation as resolved.
Show resolved Hide resolved
proc processClient(server: AsyncHttpServer, client: AsyncSocket, address: string,
callback: proc (request: Request):
Future[void] {.closure, gcsafe.}) {.async.} =
Expand All @@ -298,12 +302,20 @@ proc processClient(server: AsyncHttpServer, client: AsyncSocket, address: string
var lineFut = newFutureVar[string]("asynchttpserver.processClient")
lineFut.mget() = newStringOfCap(80)

let startTimeout = now()
while not client.isClosed:
let fds = activeDescriptors()
# The maxFDs should be replaced by the keepaliveConn?
if (fds > server.maxFDs) or ((now() - startTimeout).inSeconds > keepaliveTimeout):
break # Connection timeout

let retry = await processRequest(
server, request, client, address, lineFut, callback
)
if not retry: break

client.close() # Close the connection to not increase the number of open files.

const
nimMaxDescriptorsFallback* {.intdefine.} = 16_000 ## fallback value for \
## when `maxDescriptors` is not available.
Expand Down Expand Up @@ -339,6 +351,7 @@ proc acceptRequest*(server: AsyncHttpServer,
var (address, client) = await server.socket.acceptAddr()
asyncCheck processClient(server, client, address, callback)


proc serve*(server: AsyncHttpServer, port: Port,
callback: proc (request: Request): Future[void] {.closure, gcsafe.},
address = "";
Expand All @@ -365,6 +378,7 @@ proc serve*(server: AsyncHttpServer, port: Port,
#echo(f.isNil)
#echo(f.repr)


proc close*(server: AsyncHttpServer) =
## Terminates the async http server instance.
server.socket.close()
Expand Down