The thing that really annoys me about ZeroMQ is that sockets aren't thread-safe. This isn't such a big problem C, but it caused some really weird and difficult to track down problems in a Haskell program I wrote where I used a PAIR socket, but I wrote and read in different threads. I ended up doing some fairly unsightly socket gymnastics to get around this limitation.
Haskell programs are generally thread-safe by construction. It's very easy to overlook thread-safety in foreign libraries, but this isn't just a problem in Haskell, multi-threaded code is the default is a number of realms.
I now try to avoid ZMQ where I can. Modern libraries should be thread-safe.
Have you found any brokerless mq alternatives? About to build a haskell project and 0mq looks good. I'll keep in mind setting up two sockets, for push and pull. The documentation shows, zeromq contexts being threadsafe, wheras passing off a 0mq socket to another thread requires, putting memory barriers around it.
ZeroMQ's approach is that of many threads where you don't share any state across them, you just pass messages. I'm not an expert on the subject, so all I can say is that according to the authors of ZeroMQ, this is a good way to proceed, since coordination can take up a lot of resources.
I can only talk from my own experience. In this case, I had two processes talking to each other across a PAIR socket in an asynchronous manner. It was really convenient for me to have one thread waiting on messages on the socket and another taking input from other parts of the process and writing to the socket.
You might argue that in this case having two sockets, a PUSH and a PULL might have been better, but the nature of the communication was very much between two processes and I didn't want to weaken that.
Coordination can be expensive and certainly, actors or some sort of channel-based model (which is my preference), have their place, but when you have light-weight communication and coordination primitives, it's not a given.
The ZeroMQ documentation suggests that you should use ZeroMQ to communicate between threads within the same process, as well as between processes. Given that context it wouldn't make sense for it to be thread safe. That would be too much overhead for no benefit.
ZeroMQ is very poor at communicating between threads within the same process, because messages are just binary data. The messaging library I use shouldn't dictate the way that I program; the dog wags the tail.
That would force me into an asynchronous style, but in my case, I was able to convey intent much better using threads.
This complaint is borderline non-sensical to me. Maybe Haskell is magic?
If ZeroMQ transported anything besides binary blobs, it would be marshaling objects or enforcing some kind of encoding to your data, which would dictate much more about your program. Are you upset that you had to use some Haskell.Vector to void* to Haskell.Vector code?
Are threads in Haskell not asynchronous by nature? Do you get synchronization for free somehow?
OK, in Haskell, data is immutable. If you want to pass data from one thread to another, there is no point in serializing it, sending it between threads and then deserializing it. You can just pass a reference. The data is also not typed, but that is potentially something you could fix in the bindings.
I know that in Erlang, you do pass data by exchanging blobs, but the difference is that Erlang has per Erlang-process heaps. Haskell has one heap, so there is no reason to do this.
It comes down to this, the way that you communicate between threads in the same process is different than the way that you communicated between processes.
> Are threads in Haskell not asynchronous by nature? Do you get synchronization for free somehow?
I'm not talking about what's happening underneath. I'm talking about the style that code is written in. I suppose, I could use a coroutine style monad over ZMQ's asynchronous API and create pseudo-threads, but they wouldn't get pre-empted, so you'd have to be careful to ensure that they didn't stave.
It depends on your service multiplexing scheme.
If you are using something like NodeJS or EventMachine, then thread safety provides nothing but only increased complexity and slowness.
And 0mq is for inter-process communication. While you are running a server with many threads in one process, you usually don't need it.
While I'm arguing that modern libraries can avoid threads...
Since you have Haskell and Actors, but worrying thread-safety of some other libraries. You can consider a single-threaded/multi-process deploy.
By setting the thread pool to 1, Actors in a single process can still handle tens of thousands of concurrent connections, while there is surely no thread-safety problem.
Haskell programs are generally thread-safe by construction. It's very easy to overlook thread-safety in foreign libraries, but this isn't just a problem in Haskell, multi-threaded code is the default is a number of realms.
I now try to avoid ZMQ where I can. Modern libraries should be thread-safe.