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"?

Reply via email to