vibe.d 0.7.10 released
Sönke Ludwig
sludwig at outerproduct.org
Fri Jan 4 06:29:27 PST 2013
Am 04.01.2013 10:19, schrieb Russel Winder:
> Can someone point me at URLs I can use as examples of code and result to
> do a 5 min talk at Greach 2013 on "Why even think of Node.js or Vert.x
> when you have Vibe.d"?
>
I don't know the Vert.x API enough to be sure, but I think that they both use the same callback
based asynchronous I/O approach. Any request handler that for example has to talk to a database gets
deeply nested in asynchronous callbacks.
If you don't care about error handling, they will usually be silently ignored, because the
programming model doesn't fit exceptions or other loud forms of errors. Control flow also gets
complicated and error prone and the code becomes badly readable.
To limit this issue, node.js frequently buffers data in the background before issuing a user
callback and Vert.x falls back to synchronous I/O+threads (AFAIR, correct me if I'm wrong),
destroying all the benefits of async. I/O as soon as you have to heavily rely on that.
A simple example for node.js:
[Will probably not compile, just from the top of my head. Well, the JS version /will/ probably
compile, but fail at runtime ;)]
node.js:
---
requestHandler = function(req, res)
{
var json = req.body;
// trade memory for better code readability by reading
// everything into an array
db.items.find({kind: json.kind}).toArray(function(err, objects){
if( err ){
// really easy to forget to check this and also
// cumbersome if multiple error sources shall be handled
// the same spot
res.json({status: "error", message: "Failed to query DB"}, 500);
return;
}
if( objects.length < 0 ){
res.json({status: "error", message: "No items found for category"});
return;
}
var ids = [];
for( i in objects )
ids.push(objects[i]._id);
db.orders.insert({items: ids}, {safe: true}, function(err, objects){
if( err ){
res.json({status: "ok", message: "Failed to insert order to DB."}, 500);
return;
}
res.json({status: "error", message: "Created order"});
});
});
}
---
vibe.d:
---
void requestHandler(HttpServerRequest req, HttpServerResponse res)
{
auto json = req.json;
try { // exception handling is fully working
Bson[] ids; // simple linear control flow with normal loops
// iterate over the DB cursor as the data comes in
foreach( itm; db.items.find(["kind": json.kind]) )
ids ~= itm._id;
enforce(ids.length > 0, "No items found for category");
// no callbacks, no explicit error checking necessary
db.orders.insert([items: ids], UpdateFlags.Safe);
res.writeJsonBody(["status": "ok", "message": "Created order"]);
} catch( Exception e ){
// a single point for error handling is possible
res.writeJsonBody(["status": "error", "message": e.msg], HttpStatus.InternalServerError);
}
}
---
Already for this simple example it's 24 lines vs. 14 lines of code and a lot of nesting. It gets a
lot worse if two DB queries would have to be done here to get the end result, but I can't be
bothered to write the necessary code now ;). But a really important point for server software IMO is
that you should be _required_ to handle errors instead of that being an opt-in or forget thing, a
mere 'error' parameter just cries for bugs and possibly security holes.
The rest of the argument, I think, is mostly generally about D vs JS/Java/Ruby (which arguably has a
lot of weight by itself) and about specific API details.
More information about the Digitalmars-d-announce
mailing list