Disrupting Java apprentices with node.js

I started lecturing a few years ago, for a while it was a fulltime job. I lectured mainly in two programming languages: C in introductory classes (first semester) and Java for OOP, data structures and distributed systems classes (equally distributed along the bachelor degree).

After a while I got bored and nowadays being a lecturer is not a fulltime job, my main contribution now is to bring fresh tech into the play and introduce it to seniors and other lecturers and this is where this story starts.

nodejs_logo

About one year ago I started diving into node.js. Initially I only used it for non critical stuff, still using Java as my main language.
I really liked node from the first day but I just didn’t have the time to dive into it at the time.
About 6 months ago everything changed, I’m really hooked into it and now I finally feel that I acquired enough skill to allow it to replace Java in my head.
Node ecosystem is awesome and it doesn’t have all that clutter that Java has, it is so clean and agile…

This semester I decided to bring node.js into a senior class and simultaneously a few senior projects.

Remember how I started this post?

In here almost every design/programming topics are taught Java, when I gave the first class about JavaScript and node.js everyone was like “WTF”?
A few students even looked at me thinking I was drunk because in their heads Javascript was for browsers and nothing else.

In order to sell them node.js I live coded a drag-n-drop DIV element that moved simultaneously in all browsers using socket.io. Instantly everyone on the room was curious about this, even the more sceptic ones. (if you want to disrupt someone show them something very graphic/explicit and that I did)
Code available at https://github.com/apocas/psi2013-node (it uses prototype based objects, modules, and events)

It’s true that I could have implemented that in almost any other language, but the lack effort needed to implement it in node.js is really impressive and that was what disrupted the audience (npm awesomeness helped :-D).

Right now seniors are starting to put their hands on node.js at multiple projects (https://github.com/portugol – Portugol rewritten in node.js) so far I feel that the hardest thing for them is the asynchronous architecture.

Although one big advantage I felt was the fact that they came from a language where everything is an Object (Java), because of this they quickly understood objects in JavaScript and how can events be used for message passing in an asynchronous environment.

In my opinion this is one of the most important thing to understand in the Javascript/node.js world.

Advertisements

cPanel + logster + graphite

cPanel servers use one accesslog per virtualhost, which they call domlogs.

This can be problematic if you want to grab metrics from your logs. Tools like logster (metrics), beaver (log collection), … are usually designed to tap one single log file.

Some months ago I rewrote beaver, implemented daemon mode, multi-file and threading. At the time it seemed a good idea, but multi-file and daemon mode is just a resource hog when you have a server with ~300 vhosts.
From now on I follow Etsy advice which is, stay with simple and cron based log processing tools.

If you just want metrics, logster is the way to go you just have to find a way to parse all domlogs.

Below is a small bash script, that finds all the access logs and push their metrics to graphite using logster.

#!/bin/bash

for file in `find /usr/local/apache/domlogs/ -type f ! -name *.gz ! -name *-ftp_log ! -name *bytes_log ! -name *.offset* ! -name *-ssl*`
do
    aux=${file//./_}
    domain=${aux##*/}
    hostname=`/bin/hostname`
    hostname=${hostname//./_}

    logster -p servers.$hostname.$domain --output=graphite --graphite-host=XXX.XXX.XXX.XXX:2003 SampleLogster $file
done

Graphite

You just have to run this script in a cronjob, cron interval will depend on how many vhosts you have and how much delay you consider acceptable in your metrics.
In graphite this will create a folder for each server, then there will be a sub-folder for each virtualhost. All this is automatically created.

I will not cover graphite in this post, installing logster in a cPanel however may require some work.

The easiest way is to install logcheck from the epel repo, do not enable this repo globally.

The problem is, to install logcheck you need some perl dependencies, which cPanel will not allow you to install them.

exclude=apache* bind-chroot courier* dovecot* exim* filesystem httpd* mod_ssl* mydns* mysql* nsd* perl* php* proftpd* pure-ftpd* ruby* spamassassin* squirrelmail*

To install them you need to edit /etc/yum.conf and remove the “perl*” exclusion, install logtail and then enable the exclusion again.

Backbone.js and i18n


backbonei18n
A few weeks ago I had to support i18n in a backbone.js project I’m developing. Many doubts quickly appeared, when to load the i18n’ed content? how? where to define it? in which format? …

I started looking into JavaScript i18n libraries/frameworks, and decided to take a look at three: i18next, jed and jsperanto.
Jed looks really good and is truly the closest thing you can get to gettext in JavaScript.

But this time I needed something simpler which could allow me to quickly delegate translations to someone without explaining all these concepts about pluralization and interpolation since the i18n that needed to be done was really simple and small.

From my perspective jsperanto is like i18next on steroids. (edit: not that jsperanto supported more features, but it felt more complex due to the lack of documentation in comparison to i18next)

I ended up using i18next, it was clean and simple solution for a simple problem with basic i18n necessities.

Initialization

Since i18next features async initialization, it is the first thing initialized and then the main backbone.js router is initialized in its callback. Something like this:

$.i18n.init({
    lng: "en-US",
    ...
}, function(t) {
    app = new Router();
    Backbone.history.start();
});

Since the main router is initialized in i18next initialization callback, I will have i18next initialized inside the app scope allowing me to call the i18n main method.

Translation

With initialization done, the only thing left was content translation.
Which in i18next is accomplished by inner html replacement in DOM elements that contain the specified i18next attribute.

I didn’t want to blind translate everything. Instead I decided to translate each backbone.js view in its rendering final stage.
Something like this:

window.ProfileView = Backbone.View.extend({
    ...
    render: function() {
        $(this.el).html(this.template(this.model.toJSON()));

        $('#profile_container', this.el).html(new ProfileInfoView({
            model: this.model
        }).render().el);

        $('.content_sub_menu', this.el).i18n();

        return this;
    }
});

.onion Mapper

Initially I had the idea of developing this during Codebits, but I ended up in developing this for fun before the event, invalidating any idea of using it.

.onion is a “non official” top-level domain suffix, the big thing about this TLD is that you can only access domains in it over the TOR network.

Due to the anonymity characteristics of the TOR network and the necessity of using it to access this TLD, very often this type of networks are called deep web.

The idea here was to crawl the .onion network, but instead of crawling and data mining its contents I just wanted to crawl its server’s relationships.

The stack is very simplistic, at the infrastructure level this was built using a main control node. Which runs node.js and a Redis instance.

Additionally there were multiple crawlers running a onion tweaked version of crawler4j, each crawler grabs the *.onion links in the html code and saves them (domains relationships) in Redis using Jedis. At the network level Polipo was used as a proxy and obviously tor client.

Each domain relationship is displayed in a graph which is rendered using sigma.js, all data is delivered to the browser using socket.io.

In two days, it crawled 1.5M urls finding and mapping relationships between 440 domains. Keep in mind that this crawling was done inside the tor network, which sometimes have very high latency times.

Finally here it is.

Codebits 2012

It was my third Codebits and by far the best one!

Codebits is an event which merges characteristics from a hackathon and a conference.

Organized and sponsored by Sapo, each year it has 800 handpicked attendees.

This year I decided to “walk the talk” and really participate into the spirit of the event: I gave a talk, saw talks, helped, got help, participated in a project (4th place :D). All this along three awesome days.

Unfortunately I didn’t have much time to meet new people, it happens when you are always running.

Here goes some photos to remember these three awesome days:

This slideshow requires JavaScript.