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