In the interests of being insensitive to execution environments aka 
reproducibility, you probably want to precede that @mrhdias program with: 
    
    
    import posix
    var fdLim: RLimit
    discard getrlimit(RLIMIT_NOFILE, fdLim)
    fdLim.rlim_cur = 1024 # fdLim.rlim_max
    echo "max-max fd ", fdLim.rlim_max, " soft ", fdLim.rlim_cur
    discard setrlimit(RLIMIT_NOFILE, fdLim)
    
    
    Run

On Linux, the hard limit is usually configured in `/etc/security/limits.conf`. 
Editing that (as root) does not take effect immediately. Re-logging in via ssh 
or /bin/login should make it active, but a reboot definitely will. You can 
inspect soft&hard limits in effect with `cat /proc/$$/limits` (more 
shell-portable/less OS-portable than limit/ulimit).

\--

As I mentioned earlier in this thread with a link to more details, "asyncfile" 
is (at least on Unix) [false 
advertising](https://forum.nim-lang.org/t/6512#40229). Regular file IO is not 
async unless you use [special purpose OS 
APIs](https://stackoverflow.com/questions/87892/what-is-the-status-of-posix-asynchronous-i-o-aio)
 or do [a non-standard system/app 
service](https://forum.nim-lang.org/t/6889#43136). So, it is no loss of 
concurrency to clients to make your IO loop: 
    
    
    var mf = memfiles.open(path) # raises if path missing/etc.
    ...
    var off = 0
    while off < mf.size:
      let data = cast[pointer](cast[int](mf.mem) + off)
      await req.client.send(data, min(chunkSize, mf.size - off))
      off += chunkSize
    mf.close
    
    
    Run

where you use `$mf.size` in your MIME type header code. I know this may only 
mask/delay your underlying problem, but I thought explicitness might help.

\--

Also, on Unix the lowest numbered file descriptor slot is always used if 
available. So, you do not need to iterate over /proc/PID/fd as per @treeform 
advice - you can just observe the maximum number fd in use in your program 
itself, though these may be unexposed/unexported by the stock Nim. (Indeed, if 
you read docs on those limits they often just say 1 + max fd ever issued by the 
kernel, not "number of fds" because these ideas are basically the same.) If you 
run your server under `strace -o bug.st` then you should be able to see if file 
descriptors being returned in system calls/passed around to others are "staying 
small numbers like 0..10" or "skyrocketing to 1024". The latter indicates a 
leak.

Reply via email to