Hello nimmers!
Long time lurker, first time poster.
I had a random problem at $dayjob that I decided would be a fun and easy fit to
use nim to solve.
There's a daemon that streams line data over a TCP socket at an interval. There
are no delimiters in the stream, and it's an unknown amount of data per
interval. After putting something together fairly quickly, I hit an exception
after a few hours:
Error: unhandled exception: Too many open files [OSError]
Sure enough, I appear to be leaking closed sockets with each connection.
test 57537 root 4u IPv4 0xfffff80024e4b410 0t0 TCP *:*
(CLOSED)
test 57537 root 5u IPv4 0xfffff8001a1e7000 0t0 TCP *:*
(CLOSED)
test 57537 root 6u IPv4 0xfffff8001ad2a410 0t0 TCP *:*
(CLOSED)
test 57537 root 7u IPv4 0xfffff800142bd820 0t0 TCP *:*
(CLOSED)
test 57537 root 8u IPv4 0xfffff80003e07410 0t0 TCP *:*
(CLOSED)
test 57537 root 9u IPv4 0xfffff80003e07000 0t0 TCP *:*
(CLOSED)
.... (etc etc etc)
I've gutted everything down to the simplest test code that reproduces the
problem.
import net
var server = newSocket()
server.set_sock_opt( OptReuseAddr, true )
server.bind_addr( Port(14865) )
server.listen()
while true:
var
client = newSocket()
address = ""
result = ""
server.acceptAddr( client, address ) # block for a client
try:
result = client.recv_line( timeout=500 ) & "\n"
while result != "":
result = result & client.recv_line( timeout=500 ) & "\n"
except TimeoutError:
echo "Done receiving data from " & address
finally:
client.close
echo address & " said: " & result
Am I misunderstanding something about close()? (I thought that freed the FD to
the kernel?) Something else naive I'm missing (some sockopt)?
Help/ideas/cluebats all equally appreciated. This is Nim 0.17.2, same behavior
on both Linux and FreeBSD.