[zeromq-dev] conventions in bindings

MinRK benjaminrk at gmail.com
Tue Jan 31 23:17:54 CET 2012


Hello all,

I am hoping for a bit of guidance on formalizing Bindings conventions,
which discussion can ultimately be added for further specificity in
the Bindings
Guidelines <http://www.zeromq.org/docs:bindings> on the Wiki.

There are a few points on which I think some specification would be helpful:

*1. Messages and Frames*

PyZMQ has a Message class, which maps exactly to libzmq's zmq_msg_t.  The
Message class is principally the coordinator of the separate refcounts in
libzmq and Python.

PyZMQ's design matches libzmq well (as that is what it is based on), but
there is an inherent problem in the degeneracy of the term 'message'
because of the notion of multipart messages.  This is extended by the
addition of `send/recvmsg` in libzmq3, where msg refers to zmq_msg_t,
rather than the actual ØMQ atom that is a multipart message.   In this way,
I prefer czmq's style of calling message parts Frames, and referring to the
collection of associated frames as a Message.

In terms of nomenclature, should bindings follow the czmq convention of
using Frame to refer to a message part, or Message, following libzmq?

If we did move in this direction, a logical name would be `send(frame)`
mapping directly to `zmq_send()` and `send_message(multipart_message)` for
the multipart case (as opposed to PyZMQ's current `send_multipart()`), but
that might cause further confusion of the fact that what libzmq means by
msg is *not* what higher level bindings mean by the word.

*2. SOCKOPT defaults*

Default values vary, and czmq makes some choices that differ from libzmq:

* SUB sockets default to SUBSCRIBE("") instead of None
* LINGER is a property of the Context, and sets a default value for its
sockets, which is 0 by default, instead of -1

Should other bindings follow these conventions?

* libzmq3 changed HWM to 1000 from inf

Bindings that support both libzmq2.1 and 3.1 could backport things like
this if we want, further hiding the transition when upgrading across
revisions.

*3. shutdown*

czmq has `zctx_destroy()`, which sets LINGER, closes sockets, and
ultimately terminates the context.  PyZMQ has *similar* behavior in
Context.destroy(), where setting LINGER before closing is an optional
argument, and does not happen by default.  The first attempt at this in
pyzmq was problematic because it was non-optional (happened on Context
deletion), and setting LINGER and closing sockets is not threadsafe.  A
threadsafe version requires something like czmq's zthread notion of
associating sockets with their respective threads.  PyZMQ opted for a
simple explanation that Context.shutdown() is not a threadsafe method, and
must be used only in single-threaded circumstances (as far as active
sockets are concerned, anyway), or at your own risk.

The argument against making some of these changes (particularly
Message/Frame nomenclature and changing sockopt defaults) is that it
introduces confusion in the documentation between explicit coverage of
libzmq, and coverage of zeromq in general, as in the Guide.  I would be a
lot more comfortable if these deviations from libzmq patterns were
formalized and highly visible, so when people ask me why default LINGER
behavior is not as described in `man zmq_setsockopt` I can point to a
community-supported document.

I think this is a discussion that would be good to have now, because
libzmq-3.1.x becoming stable may be a good time for some shifts APIs and
convention for bindings.

Perhaps we can discuss this further in Portland next month.

Thanks for your time,
-MinRK
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.zeromq.org/pipermail/zeromq-dev/attachments/20120131/4dc6c4a6/attachment.htm>


More information about the zeromq-dev mailing list