Is https://zeromq.org/ used much in Rust projects?

In C/C++/Python, I often see projects that have a dependency on https://zeromq.org/ .

I have yet to see this in Rust crates I have been reading.

I am trying to figure out if (1) my sampling is biased or (2) there is a technical reason why the abstractions zmq provides are not as useful in Rust's ecosystem.

1 Like

The zmq crate has 950k downloads, which is a fair amount in the Rust ecosystem. That said, I have never heard of this library nor personally seen it used.

1 Like

There are quite a few crates that appear to use it too https://crates.io/crates/zmq/reverse_dependencies .. I guess for some reason I've just never run into those crates. I thing I do wonder is whether zmq is solving a network issue (which would make it useful to Rust) or if it is solving C issues (which would explain it being used less.)

ZeroMQ is a (relatively opinionated) networking abstraction that is useful for implementing a variety of patterns (pub/sub, etc.), which are quite exhaustively explored in the guide. There are a couple of successor libraries (nanomsg and nng), but I think ZMQ remains the more popular library. I have used the C# implementation in a lot of projects.

I wouldn't say there is an alternative specific to rust that would make it less relevant in the ecosystem.

1 Like

I use it a tonne in my embedded (OpenWrt-based) projects, just for IPC. The key features for me are (a) internal handling of reconnects, atomic message sending, etc. and (b) I can swap out an IPC socket for a TCP socket transparently and run eg. the hardware layer on the real device and the other systems on a desktop.

I thing I do wonder is whether zmq is solving a network issue (which would make it useful to Rust) or if it is solving C issues (which would explain it being used less.)

It is a bit of both; I think one reason you don't see it as much in Rust is that it's easier and almost mandatory to write robust error handling code for lower level sockets; plus you have channels for internal inter-thread message passing (one big use case for ZMQ in C). The other advantage it confers is the ability to let C, Rust, Python etc. programs talk to each other; since Rust's ecosystem is already extremely comprehensive, it's less likely you'll need to talk Rust<->non-Rust and you can use a Rust-specific mechanism.

I am trying to figure out if (1) my sampling is biased or (2) there is a technical reason why the abstractions zmq provides are not as useful in Rust's ecosystem.

I don't think it's (2); I also haven't seen it used much so maybe not (1) either. I suspect it's (3) - for reasons of timing, commerce, interest etc. Rust projects currently just aren't the sort to need what ZeroMQ is offering.

2 Likes

Something to point out is that you don't often need all the flexibility that ZMQ gives you. For example, most cloud applications wouldn't bother with ZMQ because they'll just use a pub-sub or message queue service from their cloud provider.

Similarly, for in-process communication there are more ergonomic solutions like channels and actor frameworks which let us pass around message objects without needing to serialize/deserialize.

We also have native async/await which isn't something C++11 has access to, meaning you will come up with different ways to do networking and handle concurrency.

Another thing to keep in mind is that the zmq crate binds to the C library, and build systems (especially autoconf) are a massive pain to integrate into a cross-platform project. Running cargo build in a pure Rust project tends to Just Work, regardless of whether you are on Windows, Linux, or MacOS. On the other hand, projects which link to native libraries tend to require tweaks like installing packages, using mingw on Windows, or setting random environment variables.

2 Likes