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
_______________________________________________ zeromq-dev mailing list zeromq-dev@lists.zeromq.org http://lists.zeromq.org/mailman/listinfo/zeromq-dev