Open sveri opened 4 years ago
Are you sure that OptReusePort is supported on Windows? It's a fairly new feature even on Linux.
That's a good question. I didn't even think about it to be honest. I just read through this extensive answer: https://stackoverflow.com/questions/14388706/how-do-so-reuseaddr-and-so-reuseport-differ and it seems like it's even considered a security problem if sockets can be hijacked. My knowledge in this area is pretty slim, I just assumed it worked on linux, so it should work on windows, but, that seems not so. Maybe someone with more knowledge can chime in?
I encounter similar problems when porting httpbeast to windows(my fork). Enabling multi-threads in windows makes Prologue running slower than single thread. https://github.com/planety/prologue
It is not specific to async await. It also happens with synchronous net
.
import net, os
type
Server = ref object
socket: Socket
proc newServer*(): Server = new result
proc close*(server: Server) =
server.socket.close()
proc sendResp*(socket: Socket, code: string) =
socket.send("HTTP/1.1 " & code & "\c\L" &
"Content-Length: " & $((code).len + 2) & "\c\L\c\L" &
code & "\c\L")
proc processMessage(server: Server, csocket: Socket) =
echo "threadid: " & $getThreadId()
try:
let line = csocket.recvLine()
if line.len == 0:
csocket.close()
csocket.sendResp("200 OK")
except Exception as e:
echo osLastError()
echo "Failed processClient(): " & e.msg
proc loop(server: Server, port = 5000) =
server.socket = newSocket(buffered = false)
server.socket.setSockOpt(OptReuseAddr, true)
server.socket.setSockOpt(OptReusePort, true)
server.socket.bindAddr(port.Port)
server.socket.listen()
var netAddr: string
var clientSocket: Socket
while true:
server.socket.acceptAddr(clientSocket, netAddr)
echo "accepted connection from " & netAddr
processMessage(server, clientSocket)
proc runServer() =
let svr = newServer()
loop(svr)
svr.close()
proc start*() =
var threads = newSeq[Thread[void]](4)
for i in 0 ..< 4:
createThread[void](threads[i], runServer)
echo("Listening on port 5000") # This line is used in the tester to signal readiness.
joinThreads(threads)
start()
When I try to spawn multiple threads that call an async function on windows, everytime the same thread is used (as can be seen in the output). The same code on linux spawns and uses multiple threads as expected.
Example
Current Output
Expected Output
Possible Solution
Additional Information