[zeromq-dev] What do I need to do to create a subproject of the libzmq?

john skaller skaller at users.sourceforge.net
Mon Feb 13 03:49:11 CET 2012

On 13/02/2012, at 1:09 PM, niXman wrote:

> Hello ØMQ dev-list!
> I want to create a subproject of the ØMQ the main direction of which will be:
> 1. full implementation of the C++ API. not as cppzmq project, which is
> in fact a wraper over C API.
> 2. use of exceptions.

Don't do it. Not yet. Before you think about this you should
carefully examine the Felix binding.

I use a technique there called "phantom types" where the error
handling method is parametrised on a dummy type parameter.

You can then provide different error handling methods which apply
across the whole API by making specialisations for dummy type
arguments of the dummy type variable.

I believe the same technique can work in C++.

This means, the client can chose an instance which throws
exceptions. Or, they can choose one which calls a function
which might log the problem and then throw an exception.
The client chooses the kind of exception they want, one which
agrees with their existing method of catching them.

If you just throw exceptions, you place a huge burden on the
client to catch them in appropriate places: this is probably
WORSE than having to check a return code because it's
necessarily non-local to the origin of the problem.

By using this technique you are leaving it up to the
client to decide how to handle errors. You just provide
systematic detection .. let the client provide the handling method.

Just to explain: you basically call something like:

	Zmq_error_handler<T>::error_handler(e, errno, file, line); 

in your binding. You declare

	template<class T> void error_handler(int, errno_t, char *, char*);

but don't define it. The client then defines a specialisation like:

	struct log_and_throw_t;
	template<> void error_handler<log_and_throw_t> ( 
		int e, errno_t err,
		char *file, char *line
	) { 
		cerr <<  "Some error" << endl;
		throw MyKindOfError (file, line);

and uses zmq like:


If you put ZMQ functions in a class template and use static members,
and then a typedef:

	typedef Zmq<log_and_throw> ZE;

you can do:

	ZE::init (2);

etc. A bit of verbosity, but you have control over error handling 
(on a call by call basis if necessary).

BTW: one of the most curious error handling methods is to use write a log
message to a ZMQ socket, then wait for a reply. The client then connects
to the socket, copies the log stuff to their console, and gets to type
in a command to the process what to do. In particular if they're running
under a debugger they might ask for a backtrace or something ..
remotely. The client side might also ring a bell and make the coffee whilst
the programmer is waking up to see why the server crashed.

john skaller
skaller at users.sourceforge.net

More information about the zeromq-dev mailing list