[PATCH] AnyEvent::Handle

Maxime Soulé btik-cpan at scoubidou.com
Wed Jul 4 10:40:25 CEST 2012


Le 03.07.2012 20:30, Marc Lehmann a écrit :
> On Tue, Jul 03, 2012 at 12:00:36PM +0200, Maxime Soulé<btik-cpan at scoubidou.com>  wrote:
>> Because this behavior is not consistent across all type readers. With
>
> Actually, the behaviour is consistently undefined over all read types.

I agree with you :)

>
>> I have in mind general application exceptions, like a perl critical
>> one.
>
> What is a perl critical exception?

Like a call to a method from a undef $obj, a call to an nonexistent 
function or method, for example...

>
>> I prefer to handle this fatal case at the application level than
>> to hide it behind an error code EBADMSG and continuing to work.
>
> And nothing in AnyEvent prevents that from you. In fact, it even encourages
> you to catch exceptions. It does not catch exceptions for you (unless you use
> AE_DEBUG_WRAP or something similar).

In storable case, it does catch exceptions for me, that is the problem.

To get round that, I need to put an eval {} in my callback with a 
"catch" block that call AnyEvent::postpone to "die" later, just in case...

All of this is not needed for chunk, line, regex, netstring, packstring, 
json and tls_detect (and so tls_autostart).

It is just a pity to not have the same simple behaviour for storable 
than for others in the same module, and so perhaps at the same time, 
define one for all read_type writers.

Of course I can define a new storable read type, but that is not the 
goal, I think it is better to talk about existing code :)

To clarify, and perhaps to make my problem more understandable, I 
implemented a protocol in which the serialization is negotiated at the 
beginning of the connection. After this negotiation, I use json, 
storable or msgpack without having to care about the underlying 
serialisation mechanism. The great flexibility of AnyEvent allows that 
very easily.

>
> Note that netither catching or letting through, an exception from a read
> type, will cause  anything remotely similar to "handling at application
> level", because you are always at a whim of whatever is in your callstack,
> which most often is the event loop.
>
> If you want any kind of specific behaviour, then you need to implement
> that.  Relying on whoever else is up the stack is not going to work.
>
>>> In fact, if caught via this mechanism it at least has a chance of getting
>>> reported in a defined way (although it's still a bug).
>>
>> Or not
>
> Since ou disagree, can you describe the mechanism that takes away the
> chance of it being reported?

The main $cv->recv is included in an eval {}, so I can catch the error, 
log it before aborting the program, because I consider, in my case, that 
these untrapped exceptions are fatal ones. This mechanism is application 
dependant, this is one example I use.

>
>> When an EBADMSG is reported, it says that probably the client sent
>> wrong data, so we can disconnect it and continue to work.
>
> No, *any* program behaviour can always be caused by a bug as wlel, as
> would be the case in this case.

Of course, but it could be cool to be able to easily detect "perl 
critical exceptions" without having to obstruct my callback with 
eval/catch block...

>
>> In the application fatal error case, it is not the same, the problem
>> can be (and is probably) more serious...
>
> AnyEvent cannot know which errors are and are not fatal to your
> application. It could wrap each watcher callback into an eval to get some
> defined behaviour (and you can do that using the wrap functionality), but
> it does not enforce this.

Please, excuse me to insist :), but in the storable case, it does 
enforce this.

>
> Exceptions thrown from callbacks simply result in undefined behaviour, not
> "application level error handling" or anything else. And I really mean
> undefined behaviour - sometimes you get random memory corruption, sometimes
> you get a message on stderr, sometimes it gets ignored, and sometimes you get
> even more funny behaviour.
>
> It is simply a bug, no matter what AnyEvent::Handle does.

I agree with you, a bug is a bug. It could just be cool that 
AnyEvent::Handle only catches exceptions in its own code, but not in the 
user code (except when the user wants it by using AE_DEBUG_WRAP) and let 
the application handle all other exceptions, because only the 
application knows exactly what to do in such cases.

Please note that all that discussion comes from the position of an eval 
{} in a code line ;-)

Best regards,

Max.



More information about the anyevent mailing list