[zeromq-dev] libzmq v4.0.5

Pieter Hintjens ph at imatix.com
Thu Sep 25 14:20:07 CEST 2014

On Thu, Sep 25, 2014 at 1:39 PM, Goswin von Brederlow <goswin-v-b at web.de> wrote:

> 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.

We've already done this, and no-one complains:

- zmq_send
- zmq_sendmsg
- zmq_msg_send
- zmsg_send
- zstr_send
- zframe_send
- zsock_send
- zactor_send

All do kind of the same thing. The only time people complained
(rightly) was when 3.0 changed zmq_send.

In practice you don't get 20 variations. You get 2 or 3, one for each
stable generation. Remember we can change draft APIs at will. We make
a stable release maybe once a year. We save old APIs for a few
generations, then delete them.

> HTTP does do exactly that. When you connect you say:
>     GET /index.html HTTP/1.1

Yes, except it's used for almost nothing significant, and there was
never a successful 1.2 or 2.0. That kind of proves my point. (I've
written many complete HTTP server stacks.)

> Which is fine if you follow your own contract. Zeromq has broken it 3
> times now so that isn't the best track record.

Indeed. However this isn't my project, it's *our* project and we all
enforce the rules, or we don't. My job has been to define workable
rules. I'll enforce them on aspects of the project I use and thus care

Anyone using those pieces that got broken had the tools to stop that
happening, and didn't say anything. We can investigate why, and fix
that, if someone cares.

> 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.

Indeed. You can already do this in several ways. You don't need to
expose ABI versions for this. Indeed we have a good, existing
mechanism for feature updates to socket types. Check the many ROUTER
socket options.

> 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.

OK, I do accept the problem statement of multiple versions of an API.

There are many solutions. Remember our focus is distributed software
and a distributed community. This is important. It means we work on
many pieces at the same time, and they evolve independently over a
long time, and at a distance.

What this means is that we do not have a single API contract stream.
Yes, you can say "this is version X" however you cannot use the version
number as a mechanism for changing semantics.

Here's the proof: you have piece A and now someone wants to change that
to A'. New version number. Now, user can choose between A and A' using
the version number. However now we want to improve A and make A''. This
is not an improvement of A'. How does this work? New version again?

We've effectively forced an internal fork of the code. Now multiply
this by the number of aspects we play with.

This is why I called it "insane".

The sane and simple solution, which we use and which is proven, is to
use different namespaces that can evolve independently, and never break
existing code.

This is how we have lots of socket options, how we have many CZMQ classes,
and so on, and how this all works with many old versions and in a real
distributed community, without version madness or internal confusion.


More information about the zeromq-dev mailing list