I used asyncdispatch/asyncnet to implement my networking (currently).
I've got a problem "closing the server socket".
Initially I wrote something like this:
proc initCluster(port: Port, address: string) {.async.} =
## Initiates the cluster networking.
echo("Opening server socket...", getThreadId())
var server = newAsyncSocket()
server.setSockOpt(OptReuseAddr, true)
server.bindAddr(port, address)
server.listen()
while true:
let peer = await server.accept()
asyncCheck processPeer(peer)
Idk if it worked, because I haven't tried it yet, but it ran without error.
Then I decided to add code to gracefully terminate the process, like this:
var server: AsyncSocket
## The server socket
proc initCluster(port: Port, address: string) {.async.} =
## Initiates the cluster networking.
echo("Opening server socket...")
server = newAsyncSocket()
server.setSockOpt(OptReuseAddr, true)
server.bindAddr(port, address)
server.listen()
while (server != nil):
let peer = await server.accept()
asyncCheck processPeer(peer)
proc deinitCluster() {.async.} =
## De-initiates the cluster networking.
if server != nil:
echo("Closing server socket...")
try:
server.close()
except:
discard
server = nil
else:
echo("Server socket not open.")
But was told by the compiler that "initCluster()" is now not GC-safe, as I use
a global ref to a GCed object.
So my thought was, well, with asyncdispatch, "everything" is meant to run in
the same thread (which I was obviously wrong about), somehow without blocking,
so I can just change "server" to a "{.threadvar.}", to make the compiler happy.
If I do, the compiler is happy, but "deinitCluster()" does nothing, because it
doesn't actually run in the same thread as "initCluster()" (verified by using
getThreadId() in the output; "initCluster()" runs in thread #2940, and
"deinitCluster()" runs in thread #4860).
So, what is the correct way to close my async server socket?
And, more generally, does that mean I still need to use shared-heap to pass
messages/signals across async tasks? Is there a way to say "run this async task
in the same thread as that other async task"?