[zeromq-dev] What do I need to do to create a subproject of the libzmq?
niXman
i.nixman at gmail.com
Mon Feb 13 05:05:46 CET 2012
2012/2/13 niXman <i.nixman at gmail.com>:
> 2012/2/13 john skaller <skaller at users.sourceforge.net>:
>>
>> 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:
>>
>> Zmq<log_and_throw>::init(2);
>>
>> 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);
> In my opinion, is too complicated.
>
> std::shared_ptr<zmq::session> session;
> try {
> session.reset(new zmq::session(...));
> } catch ( ... ) {
> ....
> }
>
> ...
>
> // synchronous
> session->send_message(message_type(...)); // throw an exception
>
> // synchronous
> std::error_code ec;
> session->send_message(message_type(...), ec); // set ec on error
> assert(!ec);
>
> // asynchronous
> session->send_message(message_type(...),
> [session](message_type& msg, const std::error_code& ec) {
> if ( !ec ) {
> ... some code ...
> } else {
> ...
> }
> }
> ); // never throw an exceptions
>
Oh yeah, forgot about socket :)
>
> And yet, what should I do to create a subproject?
>
>
>>
>> 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
>>
>>
>>
>>
>> _______________________________________________
>> 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