Archive

Archive for October, 2011

Shinken thruk_server.pl compilation error fix

October 26, 2011 Leave a comment

Heard about Shinken when searching for issues related with Nagios and decided to give it a try on my Ubuntu 10.10 (32bit) a try by following this script. Everything went well except then I try to start thruk (the http admin ui) I got the following error

ERROR: this is the wrong precompiled version, your archname is: i686-linux-gnu-thread-multi

BEGIN failed–compilation aborted at /opt/thruk/script/thruk_server.pl line 18.

By looking into the code, the perl script is expecting
/opt/thruk/local-lib/lib/perl5/i686-linux-gnu-thread-multi
but instead I got
/opt/thruk/local-lib/lib/perl5/i486-linux-gnu-thread-multi

So the fix can’t be simpler, simply do

cd /opt/thruk/local-lib/lib/perl5
ln -s i486-linux-gnu-thread-multi i686-linux-gnu-thread-multi
Categories: linux, Shinken

Node.js example 2: parallel processing

October 15, 2011 Leave a comment

[ UPDATE 2/29/2012 ]
I just discovered a much better way to perform the same parallel processing task through the answer by Linus G Thiel to one of my stackoverflow questions.

        var async=require('async');
        // gen an integer between 1 and max
        function gen_rnd(max) {
                return Math.floor( (Math.random()*max+1)*1000 );
        }

        function job(lbl, cb) {
                console.log('Job %s started', lbl);
                console.time(lbl+'-timer');
                setTimeout( function() {
                        console.timeEnd(lbl+'-timer');
                        cb(null, lbl.toUpperCase());
                }, gen_rnd(5) );
        }

        console.time('all jobs');
        async.parallel([
                function(cb) { job('p1',cb) },
                function(cb) { job('p2',cb) }
        ], function(err, results) {
                console.log('do something else upon completion of p1 and p2');
                console.log('results=%j', results);
                console.timeEnd('all jobs');
        });

[ Original version of this post ]
I just wrote another example using Node.js to demonstrate the benefit of non-blocking io programming. In this example I need to do a job that depends on two processes p1() and p2(). Job won’t start until both p1 and p2 are finished. If I start p1 and p2 one by one, the total time used to do job would be at least T(p1)+T(p2). But if I can start p1 and p2 in parallel then the time required would be reduced to Max(T(p1), T(p2)). To make the simulation closer to real-life examples, the execution time for p1 or p2 would be anywhere between 1 and 6 seconds. So if you run this example you will see sometimes p1 is finished early, sometimes p2 is. The core part of this example uses event.Emitter.

Update 11/6/2011: using console.time and console.timeEnd to keep track of time consumed

var util=require('util');
var events=require('events');
var max_sleep=5000; // simulated maximum execution time in milliseconds for each process
var cnt=0;

function p1(jobs) {
    console.time('process-1');
    var slp=Math.floor(Math.random()*max_sleep)+1000;
    setTimeout( function() {
        cnt++;
        console.timeEnd('process-1');
        if(cnt>=2) {
            var m='from p1, cnt='+cnt;
            console.log(m);
            jobs.write(m);
        }
    }, slp );
}

function p2(jobs) {
    console.time('process-2');
    var slp=Math.floor(Math.random()*max_sleep)+1000;
    setTimeout( function() {
        cnt++;
        console.timeEnd('process-2');
        if(cnt>=2) {
            var m='from p2, cnt='+cnt;
            console.log(m);
            jobs.write(m);
        }
    }, slp );
}

function Jobs() {
    events.EventEmitter.call(this);
}

util.inherits(Jobs, events.EventEmitter);

Jobs.prototype.write=function(data) {
    this.emit('ready', data);
}

var jobs=new Jobs();

jobs.on('ready', function(data) {
    console.log('Received data: '+data);
    console.log('Job done!');
    console.timeEnd('all-processes');
});

console.time('all-processes');
p1(jobs);
p2(jobs);

Output examples:

1-
process-1: 1724ms
process-2: 3232ms
from p2, cnt=2
Received data: from p2, cnt=2
Job done!
all-processes: 3241ms

2-
process-2: 1377ms
process-1: 4803ms
from p1, cnt=2
Received data: from p1, cnt=2
Job done!
all-processes: 4805ms

Learning Node.js + socket.io – a simple streaming example.

October 14, 2011 6 comments

I learned about Node.js not too long ago (Node is actually very new) and found its non-blocking io very interesting. Socket.io is a Node module that enables real-time communication between web client and server. It basically chooses the best supported streaming technology for the client if native streaming technology is not available (Websocket for example). I am a total beginner to both Node and socket.io and I wrote a little more complicated example than the basic one on socket.io home page. In this example, a random number is generated every 4 seconds and broadcasted to the network (see the video link at the end of this post).

Server:
Install socket.io if it’s not installed:
npm install socket.io -g

var io = require('/usr/local/lib/node_modules/socket.io').listen(8080);
var t;  // I usually don't like using global variables but hope it's ok for DEMO's purpose

function rnd() {
    var num=Math.floor(Math.random()*1000);
    return num;
}
io.sockets.on('connection', function (socket) {
    t=setInterval( function() {
        var n=rnd();
        socket.broadcast.emit('stream', {n:n.toString()});
    }, 4000);
    socket.on('action', function (data) {
        console.log('received action');
        if(data.todo=='stop') {
            socket.broadcast.emit('stream', {n:'Stopped'});
            console.log('stopping timer now.');
            clearInterval(t);
        } else if(data.todo='run') {
            // the setInterval code definitely can
            // be combined/optimized with the one above
            // again for DEMO's sake I just leave it as is
            t=setInterval( function() {
                var n=rnd();
                socket.broadcast.emit('stream', {n:n.toString()});
            }, 4000);
        }
    });
});

Client:
Note:
The client socket.io.js code can be found at /usr/local/lib/node_modules/socket.io/node_modules/socket.io-client/dist on my Ubuntu 10.10

client.html, served using Apache (I know this can be changed to use Node.js totally, with some help from Express webframe)

<script src="socket.io.js"></script>
<script>
    var sw='run';
  var socket = io.connect('http://192.168.1.200:8080');

  socket.on('stream', function (data) {
        document.getElementById('number').innerHTML=data.n;
  });

    function stop_timer() {
        if(sw=='run') {
            socket.emit( 'action', {todo: 'stop'} );
            sw='stop';
        } else {
            socket.emit( 'action', {todo: 'run'} );
        }
    }
</script>
<div style="border:1px solid #ccc" id="number">&nbsp;</div>
<a href="#" onclick="stop_timer();return false;">Action</a>

Here’s a quick video made with ScreenFlow (didn’t purchase so pls forgive the watermark):

Facetime “The server encountered an error processing registration please try again later” fix on Hackintosh

October 1, 2011 4 comments

I have Lion running on my hackintosh (thanks to http://www.tonymacx86.com/) and the usb camera that I have (a Logitech QuickCam Orbit AF Webcam) happens to be supported by my build so I fired up Facetime the other night only to find the following error:

The server encountered an error processing registration please try again later

after the login credential is verified. After reading some posts on the forum I found the solution here and it turns out to be quite easy to fix: just download, install the latest Chimera (current version 1.5.4) from here, followed by a reboot and voila, the error no longer gets in the way. Loving my hackintosh.

Categories: lion, mac osx, Tip

Replace if … then … fi with && and || in Bash

October 1, 2011 4 comments

&& and || are the shorthand of if … then … fi in Bash. They
are very useful in writing simple scripts, for example:

1. Run script based on day of week:

[ $(date +%w) -eq 6 ] && echo "do something on Saturdays" || echo "do different things on other days"

The equivalent if block of the above would be:

if [ $(date +%w) -eq 6 ]; then
    echo "do something on Saturdays"
else
    echo "do different things on other days"
fi

If more commands are needed when if condition matches (or doesn’t match), you can use { } to put the commands together

[ $(date +%w) -eq 6 ] && {echo "do something on Saturdays"; do_some_other_stuff; exit 0;} || echo "do different things on other days"

The shorthand also makes it easier to write stuffs to crontab, for example, we can put the something like this to crontab

1 8 * * * [ $(date +\%d) -eq 1 ] && ~/scripts/run_stuff_on_first_day_of_a_month

The ‘%’ is escaped, you can check out my another post regarding this.

2. Make sure a specific mount exists
Sometimes we need to make sure a mount point exists before any other tasks can be performed, it’s quite simple to do it with the shorthand form of conditional block:

mount|grep -q "^/dev/sdb1 " || mount /mnt/datastore

This will ensure partition /dev/sdb1 will be mounted to /mnt/datastore. A couple of things are worth pointing out:
1) grep option -q will suppress std output from grep, results are stored in $?, from which operator || will determine to run “mount /mnt/datastore” or not.
2) ^/dev/sdb1 instead of /mnt/datastore is used for the regular expression to eliminate false match. It’s unlikely but possible that the following mount point might exists
/dev/somepartition on /mnt/datastore 2 (ext3, local …)
An additional space is inserted to the end of the regexp in case there are partitions such as /dev/sdb1X (x=0-9) mounted.

3. Make sure a specific folder exists, if not, create it before script runs. For example:

[ -d /tmp/mydir/work ] || mkdir -p /tmp/mydir/work
Categories: Bash, Programming, Tip