[zeromq-dev] libzmq v4.0.5

Goswin von Brederlow goswin-v-b at web.de
Thu Sep 25 13:39:04 CEST 2014

On Thu, Sep 25, 2014 at 09:00:28AM +0200, Pieter Hintjens wrote:
> On Thu, Sep 25, 2014 at 4:22 AM, Goswin von Brederlow <goswin-v-b at web.de> wrote:
> > Well, and a third time now. Both the "now blocks" and changed monitor
> > events are API changes that breaks existing stuff. One could even say
> > the ABI hasn't changed, only the API.
> The changes to the monitor API broke the rules. We should have defined
> a new API and left the old one alone and deprecated it.
> > Which makes me wonder. How could we prevent this in the future?
> We know how to prevent it.
> Right now a C program can say zsock_new () or zmq_sock () and get new
> or old behavior. It seems fairly logical to eventually make CZMQ a
> part of libzmq to reduce building and packaging costs. That's a
> detail.
> Can you identify any reason that doesn't work?

That is fine for major changes where a completly new function makes
sense. But not for minor behaviour changes that only conern corner
cases. It doesn't make sense to end up with 20 zmq_sock() like
functions that all return a slightly differently behaving socket.
> > Calling 'zmq_init_ver (1, 3);' would give the old behaviour while
> > 'zmq_init_ver (1, 4);' would activate the behaviour we currently have
> > and remain there. When more changes are added a API version 5 would be
> > added, then 6 and so on.
> On the plus side, it lets the caller explicitly demand one version or
> the other. On the minus side, it is an insane solution to a
> non-problem. The ideal solution for users is to see no versions at
> all, and for developers to be able to add and remove pieces without
> shifting gears.
> Can you imagine if HTTP had such a scheme, and in order to get a new
> content header you had to change versions and ask the entire Internet
> to upgrade? "Sorry, you can't watch Youtube because your browser is
> using Internet v12.0.3.1, you have to upgrade."

HTTP does do exactly that. When you connect you say:

    GET /index.html HTTP/1.1

The "1.1" at the end specifies the protocol version to use and
determines what features and capabilities you have. And a while ago
there was talk about a new HTTP/2.0.
> That is what this scheme aims at.
> Public contracts should not be versioned. They should be frameworks

Which is fine if you follow your own contract. Zeromq has broken it 3
times now so that isn't the best track record. And there are a number
of things I would like to change eventually. Like ZMQ_STREAM sockets
shouldn't require the MORE flag for every frame, alternating between
destination and data frames. Instead they should work like ROUTER
sockets and take the first frame of a multi-part message as the
destination address and send the rest onwards.

> into which pieces can be added and removed asynchronously, where each
> piece has a rolling contract, and where contract violations are
> visible upfront (as compile errors, in C).

That I think is the advantage of the FUSE solution. By defining a
higher FUSE_USE_VERSION you can not only get new features enabled but
also deprecated features removed. So while FUSE_USE_VERSION 21 would
still have foobar(), with compatibility code, a FUSE_USE_VERSION 26
would give a compile error when you try to use foobar(). The lib would
still have foobar() in both cases, the header file just doesn't expose
it anymore if you specify the new version.

You can even have the function there in version X, emit a deprecated
warning on use with version Y and hide it with version Z.

> Insanity is what you often get when you try to solve non-problems.
> That's why I'm so adamant about starting with problem statements, not
> "we could do X or Y" discussions.

Problem: You have 2 differently behaving APIs and want to support both,
but not necessarily at the same time.

Current solution: Ignore the API change and bump the SOVERSION to alow
existing code to function with an old libzmq3 and new code with
libzmq4. Which also means changing the packaging for all reverse
dependencies (for Build-Depends: libzmq4-dev) under Debian and
recompiling them even though only one of them is affected by the

Idealy I would like to just have libzmq-dev and libzmq3 and have that
work for both old and new sources and binaries.

> Our process is to identify a problem with the current situation, then
> solve that minimally and plausibly, then deliver that to real users,
> then repeat.
> Cheers
> Pieter
> >
> > Fuse has something similar but at a compile time property.
> > /usr/include/fuse/fuse.h:
> >
> >      * This file defines the library interface of FUSE
> >      *
> >      * IMPORTANT: you should define FUSE_USE_VERSION before including this
> >      * header.  To use the newest API define it to 26 (recommended for any
> >      * new application), to use the old API define it to 21 (default) 22
> >      * or 25, to use the even older 1.X API define it to 11.
> >      */
> >
> >     #ifndef FUSE_USE_VERSION
> >     #define FUSE_USE_VERSION 21
> >     #endif
> >
> > Defining the FUSE_USE_VERSION in the application actually changes the
> > API and if unset you get the base version.
> >
> >
> > What do you think? Could we use one of those methods? Are there better
> > ways?
> >
> > MfG
> >         Goswin


More information about the zeromq-dev mailing list