-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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, against devel branch. #18205
Conversation
The client header "connection" if equal to "keep-alive" is disabled whenever the number of file descriptors exceeds the specified maxFDs or exceeds the keep-alive timeout. If the value of header "connection" equal "close", the connection is closed, if it is "keep-alive" it remains open and the number of file descriptors increases and the server die. To avoid this issue the "keep-alive" connection is disabled. It is temporary until the number of files descriptors goes down, when the value goes down the connection can remain open. It also solves the issue when the "connection" is equal to "update".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please see my comment in #18161 (comment) on what the approach should be.
I took a look at the asyncdispatch file and I think the activeDescriptors function doesn't read the real number of open file descriptors! import posix
import strutils
import os
proc getFdForProcess(pid: int): int =
var count = 0
for path in walkPattern("/proc/$1/fd/[0-9]*" % $pid):
inc(count)
return count
let pid = getpid()
echo getFdForProcess(pid) My only goal is to make the http server stay up and running and not die like it does now. |
Yes, and you can do that by following what I suggest. |
did you measure? for me it's 3s per 1M calls, ie 3us per call; compared to typical network latencies (with order of magnitude of 10ms or 100ms), this is nothing; furthermore it could be cached for a small duration if needed for extra performane. benchmark: import std/[posix, strutils, os, times]
proc getFdForProcess(pid: int): int =
for path in walkPattern("/proc/$1/fd/[0-9]*" % $pid):
result.inc
proc main =
let pid = getpid()
let n = 1000000
var c = 0
let t = cpuTime()
for i in 0..<n:
c += getFdForProcess(pid)
let t2 = cpuTime()
echo (t2 - t, c)
main() |
@@ -85,9 +89,10 @@ proc getPort*(self: AsyncHttpServer): Port {.since: (1, 5, 1).} = | |||
result = getLocalAddr(self.socket.getFd, AF_INET)[1] | |||
|
|||
proc newAsyncHttpServer*(reuseAddr = true, reusePort = false, | |||
maxBody = 8388608): AsyncHttpServer = | |||
maxBody = 8388608, keepaliveTimeout = 3600): AsyncHttpServer = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see also: nim-lang/RFCs#383
I took a look at python "psutils" package and has the "num_fds" function that gives he number of file descriptors currently opened for every OS. #!/usr/bin/python
# https://psutil.readthedocs.io/en/latest/#psutil.Process.num_fds
# https://github.com/giampaolo/psutil/blob/master/psutil/_pslinux.py#L2135
import psutil
p = psutil.Process()
print(p.num_fds()) |
This pull request has been automatically marked as stale because it has not had recent activity. If you think it is still a valid PR, please rebase it on the latest devel; otherwise it will be closed. Thank you for your contributions. |
The client header "connection" if equal to "keep-alive" is disabled whenever the number of file descriptors exceeds the specified maxFDs or exceeds the keep-alive timeout.
If the value of header "connection" equal "close", the connection is closed, if it is "keep-alive" it remains open and the number of file descriptors increases and the server die.
To avoid this issue the "keep-alive" connection is disabled. It is temporary until the number of files descriptors goes down, when the value goes down the connection can remain open. It also solves the issue when the "connection" is equal to "update".