0
module Main

open System
open System.Threading
open System.Threading.Tasks

open NetMQ
open NetMQ.Sockets

let uri = "ipc://hello-world"
let f (token : CancellationToken) =
    use server = new ResponseSocket()
    use poller = new NetMQPoller()
    poller.Add(server)
    printfn "Server is binding to: %s" uri
    server.Bind(uri)
    printfn <| "Done binding."
    use __ = server.ReceiveReady.Subscribe(fun x ->
        if token.CanBeCanceled then poller.Stop()
        )
    use __ = server.SendReady.Subscribe(fun x ->
        if token.CanBeCanceled then poller.Stop()
        )
    poller.Run()
    printfn "Server closing."
    server.Unbind(uri)
let src = new CancellationTokenSource()
let token = src.Token
let task = Task.Run((fun () -> f token), token)
src.CancelAfter(100)
task.Wait() // Does not trigger.

My failed attempt looks something like this. The problem is that the poller will only check the cancellation token if it gets or sends a message. I guess one way to do it would be to send a special cancel message from the client rather than these tokens, but that would not work if the server gets into a send state.

What would be a reliable way of closing the server in NetMQ?

Marko Grdinić
  • 3,798
  • 3
  • 18
  • 21
  • 1
    You can call Poller.Stop – somdoron May 21 '20 at 07:23
  • Even from a different thread? I am not entirely clear, I remember in the ZeroMQ guide saying that sockets should not be used from different threads. Does that mean that they can be created in a different thread before being passed into a `Task`? – Marko Grdinić May 21 '20 at 07:32
  • Anyway thanks. I am not sure about the semantics of passing sockets to different threads yet, but it occurs to me now that the reason the poller exception gets raised if it still has undisposed sockets is to highlight that it can be passed as an argument. Is there a reason though why disposal of a socket does not unbind/disconnect it from the ports it is using? – Marko Grdinić May 21 '20 at 09:47
  • 1
    You can create a socket in one thread and use it in another. Just don't use in the same time from two threads. – somdoron May 21 '20 at 10:17
  • 1
    Poller.Stop is thread safe – somdoron May 21 '20 at 10:17
  • 1
    When socket is disposed it should unbind. However, disposing of a socket is not an immediate action. You might want to play with Linger as well. As if you have pending messages the socket might never to away. – somdoron May 21 '20 at 10:18

0 Answers0