[zeromq-dev] conventions in bindings

Johnny Gozde johnny at jgoz.net
Wed Feb 1 00:22:57 CET 2012

On Tue, Jan 31, 2012 at 3:17 PM, MinRK <benjaminrk at gmail.com> wrote:

> *1. Messages and Frames*
> 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.

This is similar to the path I'm taking in clrzmq's version 3 support. There
will be 3 root Send* methods:

* Send(byte[], SocketOptions) -- maps directly to underlying
* SendFrame(Frame) -- sends Frame objects, which encapsulate zmq_msg_t
objects and applicable options (i.e., SNDMORE)
* SendMessage(Message) -- sends Message objects, which contain 1 or more

Each Send has a corresponding Receive:

* byte[] Receive(SocketOptions*)
* Frame ReceiveFrame()
* Message ReceiveMessage()

Including the "raw" Send/Receive methods allows for application-level
optimization, such as buffer re-use, and it keeps the C# Guide examples
somewhat consistent with the C examples.

Any functionality offered by clrzmq that doesn't map 1:1 with the libzmq
API will be documented separately, likely on GitHub.

*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?

Following said conventions will likely create a more pleasant "out-of-box"
experience for binding users by helping to avoid common library pitfalls
(e.g., not setting a subscribe prefix). As long as the binding defaults are
documented, either per-binding or globally, sharing these sane defaults
seems like a good idea.

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

Even if the binding can set socket options and forcibly close sockets in a
thread-safe way (i.e., with thread syncs), a context.destroy() method
should be considered a "last resort" approach. Much like Thread.Abort() in
.NET, destroy() should be reserved for scenarios in which quick termination
is favoured over safe termination.

clrzmq does not implement a Context.Destroy method, but I'm not opposed to
adding one as part of the standard binding features.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.zeromq.org/pipermail/zeromq-dev/attachments/20120131/c330a431/attachment.htm>

More information about the zeromq-dev mailing list