Shinken thruk_server.pl compilation error fix
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
Node.js example 2: parallel processing
[ 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.
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"> </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
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.
Replace if … then … fi with && and || in Bash
&& 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