I'm happy to announce the release of ØMQ version 2.0.7.
The new version is available immediately to download on the website, at:
http://www.zeromq.org/area:download
Please note that due to incompatible API and ABI changes in this release, all language bindings will need to be updated to work with ØMQ 2.0.7. As these are maintained by the community it may take a few days for everyone to catch up.
A big thank you to all our contributors, and special thanks to Martin Sustrik for putting it all together!
Highlights of the 2.0.7 release:
Distribution
- The core documentation has been updated with many clarifications, especially in the description of the functionality provided by the different socket types.
- The version of OpenPGM bundled with 0MQ has been updated to the 2.1.26 release.
Building
- GCC-isms have been removed from the code and build system across the board; ØMQ should now build with no issues when using compilers other than GCC.
Interface
- The zmq_init() function now has only a single parameter; the number of ØMQ I/O threads to create in the context being initialised. The app_threads and flags parameters have been removed.
- The ZMQ_P2P socket type has been renamed to ZMQ_PAIR.
- The ZMQ_LWM socket option has been removed; the low water mark for a socket is now computed automatically by ØMQ.
- A zmq_getsockopt() function has been added.
New functionality
- Multi-hop request/reply is fully supported. This feature allows the insertion of device(s) between ZMQ_REQ and ZMQ_REP sockets thus enabling scenarios such as multi-threaded server, shared service queue, and other interesting messaging topologies. The entire infrastructure is transparent to applications.
- Multi-part messages. A ØMQ message may now be composed of 1 or more message parts; each message part is an independent zmq_msg_t in its own right. ØMQ ensures atomic delivery of messages; peers shall receive either all message parts of a message or none at all. This feature allows for seamless zero-copy message passing when data are scattered in memory, and is an important building block for multi-hop messaging topologies.
- Context termination and ETERM. The zmq_term() function has been changed to interrupt any blocking operations on open sockets, causing them to return the newly defined ETERM error code. This allows for orderly application termination, especially when multiple application threads are involved.
As always, a full list of changes may be found in the ChangeLog included in the distribution tarball, or in Git.
Enjoy!

I'm new to Ømq and I'm playing with it in some wild ideas but I found confusing your statement about zmq_init.
Just for anybody who can be confused as me, in the Changelog there is the reason why app_threads has been removed: "number of application threads to use 0MQ sockets is unlimited; app_threads parameter in zmq_init is unused and obsolete"
I understand that examples like Multithreaded Server remain as they are, only changing the app_threads parameter.
Yes. This way:
zmq_init (1,2,0) => zmq_init (2)
Martin
I've fixed the article and examples.
Portfolio
Hi Martin!
first: really great work !
second: may I assume, that the identity-prefix-left-in-message-bug when using XREP/XREQ sockets in type inproc is gone in this beta-release? I checked trunk master version and found it still alive, so I wonder if i should go down to this release instead of "Master" trunk.
third: 10% performance and 90% documentation gives a better product, than 90% performance and 10% docu. The docs found are still very rudimentary and many of the features used even in example code are not to be found. I digged a lot in your source tree to guess the proper interfaces. Indeed, the most needed docs are already written by you in form of mails and example code. I'm gonna do a donation if you could just put all those peaces into the man pages or online docs … what ever is easier.
my highest regards 4 your product … it shrinked my server code by more than just a few lines since I switches from self written services to ZMQ and it nearly extincted hangups ;o)
^5
sven
Hi Sven!
Great you had good experience with 0MQ!
As for the identity, you may have noticed that there's a new concept in 2.0.7, namely "multi-part" messages. The identity have moved from being forcefully glued to your message into a separate message part.
As for the documentation, the parts that are not documented are those that are likely to change (see how XREQ/XREP message format changed between 2.0.6 and 2.0.7) so maintaining complete documentation has to do with maintaining stable branch (see the thread on the mailing list lately).
Btw, I think Pieter Hintjens was up to writing some tutorials. I don't know what's the state of matters now.
Martin
I'm working on those. First, learning to use 0MQ a little better :-)
Portfolio
I've been talking 'bout this bug … now it's workin' fine ;o)
Hi Martin !
I found some queer behaviour demonstrated in the code posted below.
Description in short:
I used the "multithreaded server" example and explicitly set the socket identifier for being able to relaunch a crashed service. During testing, I mostly had the services started, then the clients and then killed and restarted some service and all was fine ;o)
But if I start the Clients first (errorfree trying a connect to still closed socket(s)) and AFTERWARDS start the service(s) (including the inproc-queue-device from the mentioned example), the request, send by the clients while there was no service, is gone. The clients get no reply and no service worker ever gets the request. Result: the client waits endlessly for an answer.
I stripped it down to the (ugly) snipped below.
This demo code runs fine when started without param (delaying the client thread) and shows a client deadlock when started with some parameter (delaying the worker until the client has finisched sending his request and is allready waiting for an answer).
When I do not use the device in between (clients connecting to several sockets and afterward launching the service workers binding directly the socket(s)), it works fine, so I assume, it's something to do with the queue device.
Ok. I'll give it a look. Thanks for reporting the problem!
I found the source of that behaviour. It's located (as guessed) in the queue device:
logical roadmap of it goes as follows:
client thread:
- send package to queue device
device thread:
- request events of insock and outsock
- insock message will be read from insock
- insock message will be send to outsock «««< (1)
- next read loop (blocking because no more data … OK)
worker thread:
- connects to outsock of queue
- no package gets received despite (1)
I wonder, what's the difference between
(working)
and
(not working)
A-ha sounds like reasonable scenario. So poll doesn't signal OUT when new connection is opened…
Oh, I thought it was my own fault. I had the same experience, trying to use reconnection in conjuction with the "multi threaded server" tutorial. Or is it the "identity" ?