Aug 17, 2013

Node.js, part 5.1: don't you C?

Leslie Lamport once said (before many of you were even born): "You know you have a distributed system when the crash of a computer you've never heard of stops you from getting any work done". The Internet sure proved him right, as demonstrated again last night by Google and their global worldwide crash...

However, when distributed systems work as intended, interesting things do happen. For instance, if one was so inclined, one could reimplement a server in a different language while preserving interfaces and things-would-still-work.

And so, as I sipped my morning coffee, I became very much fucking inclined indeed to rewrite yesterday's Node.js zeromq server in C. Call it my stupid idea of the day... or just an interesting comparison of two pieces of code standing 40 years apart :) In the real world, one good reason to do this would be to improve performance of critical parts of your application: divide, rewrite, conquer!

Here's the ANSI89-compliant code (also on Github), the only deviance being the use of snprintf() which only made it into C99 :)

Easy to build (no Makefile, no Maven and its XML crap):
ubuntu@ip-10-35-165-93:~$ gcc -ansi -pedantic -Wextra -Wall -o worker worker.c -lzmq
worker.c: In function ‘main’:
worker.c:29:2: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘size_t’ [-Wformat]
worker.c:34:2: warning: implicit declaration of function ‘snprintf’ [-Wimplicit-function-declaration]

Let's start this C worker and hit it with some requests coming from our Node.js app:
ubuntu@ip-10-35-165-93:~$ ./worker 
Worker ready on tcp://*:3000
received some stuff 15, size=2
sent result 30
received some stuff 8, size=1
sent result 16

Nice. In all fairness, yesterday's Node.js code is quite easier to read. I did add more error management clutter in the C program, but doing without it is not an option. Love them or hate them, modern languages will spit a stack trace out when they crash: most of the time, this is enough to start investigating. On the other hand,  C will say : "core dumped" and leave you crying all the way home: so yes, you HAVE to write more C code to get roughly the same level of information. You can also see the immense power of toString() and dynamic typing, although the latter does introduces huge caveats.

So, what did we learn? Breaking down your app not only allows you to scale it piece by piece: it also gives you the freedom to rewrite critical parts, whatever your motivation is. To me, this is true modularity, something that I've rarely seen in so-called modular architectures based on Java or C#. Having classes is nice, but services are what you really need.

And yeah, for ultimate control and performance, C cannot be defeated. I'm quite scared to see it disappear from many curriculums. Kids, listen to the old man: you must learn C. You'll thank me later.

End of sermon. Now go in peace and hack at the world!

No comments:

Post a Comment