[zeromq-dev] czmq container serialization

Pieter Hintjens ph at imatix.com
Tue Jan 13 09:39:01 CET 2015

I suspect it's not been raised as an issue before because objects are
(arguably) an old-fashioned and inelegant level of abstraction for
protocols. Yes, many systems do exchange objects. However it is
(again, arguably) a bad way to make distributed systems, making fuzzy
and complex protocols, tight coupling between pieces, and overall a
more fragile system.

For this reason I think no-one has mooted the problem before. The
ideal protocols between pieces are abstracted away from implementation
details. Thus it follows we never want to send objects between pieces.
We send abstractions of things we want to do with objects.

Let me give an example. In HTTP you have an abstraction for a remote
resource (name, content length, date modified, etc.) Every server and
client has internal data structures that represent such resources. The
two layers are entirely separate. This is useful, even essential for
making successful distributed systems. The protocol does not know how
implementations work. Sending objects destroys that abstraction.

If you send structures between threads you can simply send pointers.

Hope this helps. The one plausible use case I can see for serializing
custom containers is to save/load from disk.


On Tue, Jan 13, 2015 at 1:58 AM, Alex Cornejo <acornejo at gmail.com> wrote:
> Hi all,
> As part of an application I am developing I need to serialize/unserialize a
> zlistx_t and a zhash_t into/from messages.
> In my particular use case, the elements stored in these containers
> belong to a custom czmq-style C class with its own
> my_class_new/my_class_destroy.
> When I first read the zhashx API I initially thought I could use
> zhashx_pack/zhashx_unpack (at least for the zhashx), but I soon realized
> this doesn't (and can't) work for custom types.
> The solution I adopted required the following changes:
> Implemented the following functions for the custom class:
>     // return the size of self in bytes
>     size_t my_class_size(my_class_t *self);
>     // serialize the contents of self into buf.
>     // the space used may not exceed my_class_size(self)
>     void my_class_store(my_class_t *self, void *buf);
>     // unserialize the contents of buf into a new my_class_t instance.
>     my_class_t *myclass_load(void *buf);
>     The behavior of myclass_store and myclass_load is such that the
> following
>     is a valid implementation of myclass_dup:
>     my_class_t *myclass_dup(myclass_t *self) {
>         void *buf = zmalloc(my_class_size(self));
>         myclass_store(self, buf);
>         myclass_t *other = myclass_load(buf);
>         free(buf);
>         return other;
>     }
> I also implemented the following methods for the container functions:
>     typedef size_t (size_func_t)(void *);
>     typedef void (store_func_t)(void *, void *);
>     typedef void *(load_func_t)(void *);
>     size_t zlistx_size(zlistx_t *self, size_func_t size_func);
>     void zlistx_store(zlistx_t *self, void *buf, size_func_t size_func,
> store_func_t store_func);
>     zlistx_t *zlistx_load(void *buf, size_func_t size_func, load_func_t
> load_func);
>     size_t zhashx_size(zhashx_t *self, size_func_t size_func);
>     void zhashx_store(zhashx_t *self, void *buf, size_func_t size_func,
> store_func_t store_func);
>     zhashx_t *zhashx_load(void *buf, size_func_t size_func, load_func_t
> load_func);
> You will notice the load and store function signatures for zlistx and zhashx
> are
> different than for my_class, this is to accomodate for the fact that
> these are containers and therefore must also be able to load and store
> their elements.
> Using the above methods its quite trivial to serialze and unserialize
> lists and hashes into zframes for sending messages or into binary files
> for long term storage. The same container serailization methods can be used
> regardless of the type of elements they store, as long as they implement
> the required load/store/size API for these elements.
> Although the above works, I wanted to ask experienced czqm developers if
> there is a more elegant way to implement container
> serialization/unserialization in czmq.
> Also, I would be surprised to find that I am the first czmq user that
> needs to serialize custom containers into messages. Is there a reason
> something like this is not already included in czmq's core? Should I
> polish and document this and submit a pull-request, or does this seem
> like a very uncommon use of containers in the czmq world?
> Alex
> _______________________________________________
> zeromq-dev mailing list
> zeromq-dev at lists.zeromq.org
> http://lists.zeromq.org/mailman/listinfo/zeromq-dev

More information about the zeromq-dev mailing list