On Wednesday, 31 May 2017 at 13:04:52 UTC, Steven Schveighoffer
wrote:
I have discovered an annoyance in using vibe.d instead of
another web framework. Simple errors in indexing crash the
entire application.
For example:
int[3] arr;
arr[3] = 5;
Compare this to, let's say, a malformed unicode string
(exception), malformed JSON data (exception), file not found
(exception), etc.
Technically this is a programming error, and a bug. But memory
hasn't actually been corrupted. The system properly stopped me
from corrupting memory. But my reward is that even though this
fiber threw an Error, and I get an error message in the log
showing me the bug, the web server itself is now out of
commission. No other pages can be served. This is like the
equivalent of having a guard rail on a road not only stop you
from going off the cliff but proactively disable your car
afterwards to prevent you from more harm.
This seems like a large penalty for "almost" corrupting memory.
No other web framework I've used crashes the entire web server
for such a simple programming error. And vibe.d has no choice.
There is no guarantee the stack is properly unwound, so it has
to accept the characterization of this is a program-ending
error by the D runtime.
I am considering writing a set of array wrappers that throw
exceptions when trying to access out of bounds elements. This
comes with its own set of problems, but at least the web server
should continue to run.
What are your thoughts? Have you run into this? If so, how did
you solve it?
-Steve
What things are considered unrecoverable errors or not is
debatable, but in the end I think the whole things can be seen
from the perspective of a fundamental problem of systems where
multiple operations must be able to progress successfully*
independently of each other. All operations (a.k.a. processes,
fibers, or function calls within fibers, or whatever granularity
you choose) that modify shared state (could be external to the
fiber, the thread, the process, the machine, could be
"real-world") must somehow maintain some consistency with other
operations that come before, are interleaved, simultaneous or
after.
The way I see it is that you have two choices: reason more
explicitly about the relationship between different operations
and carefully catch only the mishaps that you know (or are
prepared to risk) don't ruin the consistent picture between
operations OR remove the need for consistency. A lot of the
latter makes the former easier.
IIRC this is what deadalnix has talked about as one of the big
wins of php in practice, the separation of state between requests
means that things can mess up locally without having to worry
about wider consequences except in the specific cases where
things are shared; I.e. the set of things that must be maintained
consistent are opt-in, as opposed to opt-out in care-free use of
the vibe-d model.
* "progress successfully" is itself a tricky idea.
P.S. Sometimes I do feel D is a bit eager on the self-destruct
switch, but I think the solution is to rise to the challenge of
making better software, not to be more blasé about pretending to
know how to recover from unknown logic errors (exposed by
unexpected input).