RejectedSoftware Forums

Sign up

Pages: 1 2 3

vibe.d + exceptions

You should have been probably already aware of this, but just in case:
http://forum.dlang.org/post/ftakrucgtfcicfbkzwbs@forum.dlang.org

Re: vibe.d + exceptions

On 09/02/14 14:05 , Dicebot wrote:

You should have been probably already aware of this, but just in case:
http://forum.dlang.org/post/ftakrucgtfcicfbkzwbs@forum.dlang.org

Hello, i wanted since a long time to ask about this (as a not
experienced developer) if there is a suggested way for dealing with
exceptions as i am a bit confused with the d language documentation and
vibe.d examples i can find.
Especially when exceptions are being used for validations, database
queries and other parts that are actually part of the normal flow of the
program and need to display their messages to users . It is getting a
bit blurred the border of using them as conditionals or actual errors
(Errors are exceptional, unusual, and unexpected) because a wrong email
input is not unusual at all.

Here for example in the login function those exceptions will be thrown
thousands of times in a popular website:
userman / source / userman / web.d

try {
user = m_controller.getUserByEmailOrName(username);
enforce(user.active, "The account is not yet activated.");
enforce(testSimplePasswordHash(user.auth.passwordHash, password),
"The password you entered is not correct.");

auto session = req.session;
if (!session) session = res.startSession();
session["userEmail"] = user.email;
session["userName"] = user.name;
session["userFullName"] = user.fullName;
res.redirect(prdct ? prdct : m_prefix);
} catch( Exception e ){
logDebug("Error logging in: %s", e.toString());
string error = e.msg;
string redirect = prdct ?
prdct : "";
res.renderCompat!("userman.login.dt",
HTTPServerRequest, "req",
string, "error",
string, "redirect",
UserManSettings, "settings")(req, error, redirect,
m_controller.settings);
}

I read the above conversation but despite performance and suggestions
for improvement i was wondering if there is a recommended way to deal
with that (with current state of D and vibe.d). Let's say a summarized
advice for new users. Is this function the way to go or it would be
better to keep exceptions for exceptional situations? Or is it that the
answer is still ambiguous because of different reasons and priorities
(clear code, performance etc)?

Re: vibe.d + exceptions

tl; dr: the way vibe.d currently uses exceptions is completely unacceptable and is most notable existing performance killer.

To make usage of exceptions viable for control flow you need two changes:

1) Use preallocated (immutable if possible) exception instances. This can be done in user code and vibe.d own code

2) Don't generate stack trace in release mode (unless explicitly required). There is a pull request for DMD/Druntime to do it but it may take some time until it is merged.

Once these two conditions have been met it should be acceptable for typical web applications.

Re: vibe.d + exceptions

Am 20.02.2014 18:24, schrieb Dicebot:

tl; dr: the way vibe.d currently uses exceptions is completely unacceptable and is most notable existing performance killer.

I disagree. The way exception are currently implemented is completely
unacceptable and is the most notable existing performance killer.

Exceptions are used for error conditions, and while the case of a 404
error can and will be handled differently, all the other cases, such as
validating user input, are completely valid uses. If throwing an
exception is too slow to even use it there, the whole exception handling
system is basically completely useless. But there is no intrinsic reason
why it has to be that way.

Re: vibe.d + exceptions

Am 20.02.2014 18:24, schrieb Dicebot:

tl; dr: the way vibe.d currently uses exceptions is completely unacceptable and is most notable existing performance killer.

To make usage of exceptions viable for control flow you need two changes:

1) Use preallocated (immutable if possible) exception instances. This can be done in user code and vibe.d own code

This can be done in certain instances, but only if the exception is
immutable (at least logically immutable), and those cases are few. It
can happen quite often that an exception is stored temporarily and then
rethrown or that the data it contains is processed further. Having the
exception possibly change during that time is unacceptable - especially
in the context of concurrent tasks that may trigger the same exception.

I definitely think that 2) is the absolute minimum that has to be done
(it would probably even be enough to resolve symbols for the stack trace
lazily). And probably when that is done, there isn't even a real problem
anymore (the 404 case should still be changed).

Re: vibe.d + exceptions

On Thu, 20 Feb 2014 19:08:46 +0100, Sönke Ludwig wrote:

I definitely think that 2) is the absolute minimum that has to be done
(it would probably even be enough to resolve symbols for the stack trace
lazily). And probably when that is done, there isn't even a real problem
anymore (the 404 case should still be changed).

No, it won't be enough, I have made some quick tests with hacked changed druntime. You will never ever be able to use exceptions efficiently if those are allocated (especially if it is GC allocation that can trigger collection). It may not be notable if normal processing code also allocates regularly but than it does not make any sense to speak about performance at all.

We use exeptions in similar way in some Sociomantic code but both conditions are strictly conformed (custom runtime + always reuse instances). It is natural desire because of convenience but exceptions were never designed for throwing performance (and D spec explicitly warns about it) so you can't get it without making some sacrifices and/or restrictions. Prohibiting storing exception instances (or doing fiber switch inside catch) is smallest such sacrifice that can work.

An alternative pattern is to use version exceptions to be immutable in release code (with no fancy custom formatting) and costly allocated in debug mode.

In practice most applications don't really care though same as they don't pay much attention to allocations in user code.

Re: vibe.d + exceptions

Am 20.02.2014 22:05, schrieb Dicebot:

On Thu, 20 Feb 2014 19:08:46 +0100, Sönke Ludwig wrote:

I definitely think that 2) is the absolute minimum that has to be done
(it would probably even be enough to resolve symbols for the stack trace
lazily). And probably when that is done, there isn't even a real problem
anymore (the 404 case should still be changed).

No, it won't be enough, I have made some quick tests with hacked changed druntime. You will never ever be able to use exceptions efficiently if those are allocated (especially if it is GC allocation that can trigger collection).It may not be notable if normal processing code also allocates regularly but than it does not make any sense to speak about performance at all.

You mean GC allocated. Using a free list based allocator for example,
surely is fast enough. What's missing is a way to use manual allocators
for exceptions (safely, more or less).

I think ARC support (with a fast allocator) + lazily formatted exception
messages (using an output sink to write directly to an output range)
would be a way to solve this so that it will be far from being a DDoS
target.

We use exeptions in similar way in some Sociomantic code but both conditions are strictly conformed (custom runtime + always reuse instances). It is natural desire because of convenience but exceptions were never designed for throwing performance (and D spec explicitly warns about it) so you can't get it without making some sacrifices and/or restrictions. Prohibiting storing exception instances (or doing fiber switch inside catch) is smallest such sacrifice that can work.

But that would go completely against the safe API approach. This is
where scope could usually help, but unfortunately this doesn't apply
to the exception context.

An alternative pattern is to use version exceptions to be immutable in release code (with no fancy custom formatting) and costly allocated in debug mode.

In practice most applications don't really care though same as they don't pay much attention to allocations in user code.

Let's just say that the core package should avoid allocated exceptions
as far as possible (event code, HTTP code). The higher level code or the
DB drivers still contain enough allocations that once exceptions aren't
crazily slow anymore, their allocation shouldn't be an issue in
comparison, especially since most of them will indeed occur rarely.

But regardless of what the decision is for the application or framework,
if throwing an exception can be considered a security risk because of
DDoS, then something must be very wrong. Considering that there may be
many places where an exception is thrown in Druntime or Phobos, it would
be a very difficult task to get an application to the point where it
can't throw anymore (or even just to only have it throw pre-allocated
exceptions). You could never be certain.

Re: vibe.d + exceptions

On Thu, 20 Feb 2014 21:05:29 GMT, Dicebot wrote:

On Thu, 20 Feb 2014 19:08:46 +0100, Sönke Ludwig wrote:

I definitely think that 2) is the absolute minimum that has to be done
(it would probably even be enough to resolve symbols for the stack trace
lazily). And probably when that is done, there isn't even a real problem
anymore (the 404 case should still be changed).

No, it won't be enough, I have made some quick tests with hacked changed druntime. You will never ever be able to use exceptions efficiently if those are allocated (especially if it is GC allocation that can trigger collection). It may not be notable if normal processing code also allocates regularly but than it does not make any sense to speak about performance at all.

We use exeptions in similar way in some Sociomantic code but both conditions are strictly conformed (custom runtime + always reuse instances). It is natural desire because of convenience but exceptions were never designed for throwing performance (and D spec explicitly warns about it) so you can't get it without making some sacrifices and/or restrictions. Prohibiting storing exception instances (or doing fiber switch inside catch) is smallest such sacrifice that can work.

An alternative pattern is to use version exceptions to be immutable in release code (with no fancy custom formatting) and costly allocated in debug mode.

In practice most applications don't really care though same as they don't pay much attention to allocations in user code.

Sooo... what is the way to go here ?
I recently build the first component at work using vibe.d (a REST api) that performs quite nice as long as everything goes fine. but totally poos itself when requests reach an invalid url, that burns the CPU because of this issue..

Re: vibe.d + exceptions

On Mon, 24 Feb 2014 17:03:23 +0100, Sönke Ludwig wrote:

You mean GC allocated. Using a free list based allocator for example,
surely is fast enough. What's missing is a way to use manual allocators
for exceptions (safely, more or less).

It is not that simple. Problem is de-allocation - for raw classes destruction is not determenistic so there is no hook to call "allocator.free". Asking user to do it manually goes against safety concerns. Wrapping inside ref-counted struct can be an option but then you can't catch base classes because structs are not polymorphic.

I honestly don't know what a safe and performant solution can be here. If I ever considered using vibe.d for perfomance-critical project, I'd likely just fork it and provide status codes based rendering alternative. But that is not a solution you are loking for :)

Re: vibe.d + exceptions

Am 24.02.2014 17:35, schrieb Dicebot:

On Mon, 24 Feb 2014 17:03:23 +0100, Sönke Ludwig wrote:

You mean GC allocated. Using a free list based allocator for example,
surely is fast enough. What's missing is a way to use manual allocators
for exceptions (safely, more or less).

It is not that simple. Problem is de-allocation - for raw classes destruction is not determenistic so there is no hook to call "allocator.free". Asking user to do it manually goes against safety concerns. Wrapping inside ref-counted struct can be an option but then you can't catch base classes because structs are not polymorphic.

That's what I meant with "What's missing is a way to use manual
allocators for exceptions (safely, more or less)".

I honestly don't know what a safe and performant solution can be here.

ARC support for classes as discussed some time ago would be a
possibility. Special support for throwing RefCounted!Exception could
be another option - with proper support for polymorphism, but
unfortunately that would require different catch statements for ref
counted exceptions and for normal ones, so it would be more of a hack
than a solution.

If I ever considered using vibe.d for perfomance-critical project, I'd likely just fork it and provide status codes based rendering alternative. But that is not a solution you are loking for :)

You can just set HTTPServerResponse.statusCode instead of throwing a
HTTPStatusException, no need to fork anything. And as said, I intend
to avoid the exception for the 404 status case, too.

Pages: 1 2 3