Sunday, June 10, 2012

Killing Deadlocked Starman Processes

Every once in a while I caught a few starman workers on our live server stuck in a deadlock. Googling around it seems that this might be related to the following issues (I couldn't reproduce it in chrome incognito mode, and I don't have IE9 near my hands to test it with IE9):

https://github.com/miyagawa/Plack/issues/208
https://github.com/miyagawa/Plack/issues/191

I've resorted to killing the deadlocked processes as the starman master will happily spawn new workers afterwards. To automate this I wrote a perl script and schedule it to run via cron. The script is run at 15-minutes-interval. It checks for deadlocked starman worker processes by inspecting their cpu runtime and workload. It will kill any of the starman worker processes that has been running for quite a while with a high-ish cpu workload.

Here's the script: https://gist.github.com/2908369
Update: The issue dealt in this commit is the more likely cause for the blocking of starman processes.

Friday, August 26, 2011

How to have page up and page down in safari iPad

Add these as bookmarklets in your bookmark bar:

javascript:window.scrollBy(0,-window.innerHeight+20)

javascript:window.scrollBy(0,window.innerHeight-20)


They are for page up and page down, respectively.

Thursday, August 11, 2011

How To Optimize

Donald Knuth:


We should forget about small efficiencies, say about 97% of the
time: premature optimization is the root of all evil. Yet we
should not pass up our opportunities in that critical 3%.


(Source is here. See the 2nd paragraph on the right column on page 8.)

Here's the general advice on optimizing:

1. Don't do it
2. Don't do it yet
3. Don't do it until someone complains that it is slow.
4. And when someone complains, find the bottleneck - measure it! Get a feel of how slow it is. Remember:

Don't optimize what you cannot measure because therein lies the road to insanity.

5. Optimize one step at a time and always, always measure the gain. If there's no gain then undo your "optimization".

Wednesday, February 23, 2011

Put it out on the 'net

This is so that I'll never forget the lyric to that song that my daughter sang when she came back from daycare:

Tamiyana tam tam tam ....

Monday, December 20, 2010

Tolerable dark blue on black

sbt shows what it is doing using the color blue. Unfortunately on a black background (my preference) it is super-unreadable.

Mark Harrah said that sbt uses the ANSI escape sequence so the actual color that is used should be configurable by the terminal

Here's how to configure the color palette for xfce-terminal:

1. Edit ~/.config/Terminal/terminalrc
2. Change:


ColorPalette5=#00000000aaaa

to

ColorPalette5=#6666ccccffff


You don't have to restart anyting, xfce will update the color instantaneously as soon as you save the file.

It will change the color from this:



to this:



Neat!

Monday, April 19, 2010

No more select-and-middle-click for git (or how unix saves the day, again)

[Update 2011-07-28: You can get the code at github: https://github.com/holygeek/git-number]

I use git and rely on its 'git status' output to select the filenames that I want to operate on whatever git command that I wanted to do *now*.

I used to do this (a lot):

$ git status
[git shows the status here]
$ git [add|add -p|rm|checkout] *I reach for the mouse with my right hand, double click on the filename(s) shown in the status (so that it is selected and copied into the X cut selection) and middle click on the terminal (so that the filename is pasted here), and either hit the space bar to prepare for the next 'select-and-middle-click' another filename or press enter at this point to execute this action*

At first this felt like a quick and speedy way of selecting files to operate on but over time it gets old. I don't like reaching for the mouse and prefer that my hand stays on the keyboard. Somehow this breaks my concentration somewhat and that is not a good thing, you know, focus and all... and somehow I never get comfortable with the command line completion offered by the shell (when it comes to git) and wondered if there's a quicker way of telling git which file I want it to operate on ...

So I devised a way that I think I'll be happy using:

$ gt
# On branch master
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
#1 modified: fa
#2 modified: mF
#3 modified: poor.pl
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
#4 6a
#5 6c
#6 6cov
#7 6g


'gt' is a perl script that parses the output of git status and adds cute numbers before the tab that precedes the filenames in git status' original output. The numbers are cute because they let me know that I no longer have to reach for the mouse to tell git (or some other shell script) which file I wanted to operate on. You can think of it as the primary key that uniquely identify the file listed by git status. gt also saves its output in a hidden file, overwriting the previous content on every run.

So with this in place I can have another script, ga (which stands for git add) that accepts either the full filename or the cuter numbers as its argument so I can pretty much not go through 'select-and-middle-click' for git anymore:

$ ga -p 1 3

Which have the same effect as if I had typed "git add -p fa poor.pl" - this is *big* win for me. Yay!

What ga does is go through its argument and convert those numbers to its equivalent filename by looking at that hidden file I mentioned earlier. This is done by the following small perl library:

MyGitList.pm:

#!/usr/bin/perl
use strict;
use warnings;
package MyGitList;

my $number_pattern;
my $cmd_opt = '';

sub resolve_args {
my (@argv) = @_;
my @resolved;

foreach my $arg (@argv) {
if ($arg =~ /^[0-9]+$/) {
if (defined $number_pattern) {
$number_pattern .= '|'.$arg
}
else {
$number_pattern = $arg;
}
}
elsif ($arg =~ /^-/) {
$cmd_opt .= $arg;
$cmd_opt .= ' ';
}
else {
push @resolved, $arg;
}
}

my $resolved = join(' ', @resolved);

my $gitlist = '';
if (defined $number_pattern) {
$gitlist = `gl '$number_pattern'`;
$gitlist =~ s/\n/ /g;
$gitlist =~ s/\s*$//g;
$gitlist =~ s/^\s//g;
}
my $arg_list = "$gitlist $resolved";


return ($cmd_opt, $arg_list);

}

1;



And ga uses MyGitList.pm like so:


use strict;
use warnings;
use lib($ENV{HOME} . '/bin');
use MyGitList;

if (scalar @ARGV == 0) {
print "Usage: ga <number_pattern|filename>\n";
exit 1;
}

my ($cmd_opt, $arg_list) = MyGitList::resolve_args(@ARGV);
my $cmd = "git add $cmd_opt $arg_list";
print "$cmd\n";
system($cmd);


I love Unix.

Not too long ago I modified git status, git add, git rm, git diff, and a few more of its siblings to handle this cute numbering scheme but gave up on that because when I think about it more it seems like git is not the proper place to do it - it feels like modifying your car so that it can tell you where you stashed the coins that you had with you yesterday (there goes another not-so-useful car-computer analogy).

Thursday, October 29, 2009

When Did I Install This?

I use chrome via chromium, and I compile it every now and then, whenever I feel like it's been a while since I last compile it.

How do I know it's been a while? How long is a while?


ls -lL `which chrome`


shows me the last modification time.

But this needs some mental exercise on comparing the last modification time with the current time.

Here's my solution ...

Say hello to age:

SYNOPSIS
  age [-fh] file ...


DESCRIPTION
age shows the age of the given programs. For each argument age
locates the program executable using which(1), and then
calculates the age in days, hours, minutes and seconds. Fields
where the values are zero are not shown.

For executables age dereferences symbolic links by default.
This makes it simple to find out how old a program has been
installed on the system.

To show the age of symbolic links use the -f option instead
and specify the fullpath to the symbolic link.


Example usage:

$ age chrome
/home/nazri/bin/chrome: 1 day 21 hours 1 minute 20 seconds

$ age git
/usr/local/bin/git: 1 day 23 hours 43 seconds

$ age ls
/bin/ls: 1 year 125 days 3 hours 23 minutes 15 seconds


Neat!

Here's the full shell script:

#!/bin/sh
# age - Show age of files

me=`basename $0`
SECONDS_PER_MINUTE=60
SECONDS_PER_HOUR=3600
SECONDS_PER_DAY=86400
SECONDS_PER_YEAR=31536000

usage() {
cat << EOF
SYNOPSIS
age [-fh] file ...

DESCRIPTION
age shows the age of the given programs. For each argument age locates the
program executable using which(1), and then calculates the age in days,
hours, minutes and seconds. Fields where the values are zero are not shown.

For executables age dereferences symbolic links by default. This makes it
simple to find out how old a program has been installed on the system.

To show the age of symbolic links use the -f option instead and specify the
fullpath to the symbolic link.

OPTIONS
-h Show this help message

-f Do not locate the executable. Assume that the files are relative path
to the current directory

AUTHOR
Written by Nazri Ramliy

LICENSE
Public domain.
EOF
}

get_age() {
since=$1
now=`date +%s`
delta=$(( $now - $since ))

years=$(( $delta / $SECONDS_PER_YEAR ))
delta=$(( $delta % $SECONDS_PER_YEAR ))

days=$(( $delta / $SECONDS_PER_DAY ))
delta=$(( $delta % $SECONDS_PER_DAY ))

hours=$(($delta / $SECONDS_PER_HOUR ))
delta=$(( $delta % $SECONDS_PER_HOUR ))

minutes=$(($delta / $SECONDS_PER_MINUTE))
delta=$(( $delta % $SECONDS_PER_MINUTE ))

seconds=$delta

[ $years -gt 0 ] && out="$years year" &&
[ $years -gt 1 ] && out="${out}s"

[ $days -gt 0 ] && out="$out $days day" &&
[ $days -gt 1 ] && out="${out}s"

[ $hours -gt 0 ] && out="$out $hours hour" &&
[ $hours -gt 1 ] && out="${out}s"

[ $minutes -gt 0 ] && out="$out $minutes minute" &&
[ $minutes -gt 1 ] && out="${out}s"

[ $seconds -gt 0 ] && out="$out $seconds second" &&
[ $seconds -gt 1 ] && out="${out}s"

out=`echo $out|sed -e 's/^ *//'`
echo $out
}

find_bin=1
while getopts hf opt
do
case "$opt" in
f)
find_bin=0
;;
h)
usage
exit;;
\?) exit;;
esac
done
shift $(($OPTIND -1))

[ -z "$1" ] && usage && exit

for file in $*; do
if [ $find_bin -eq 1 ]; then
exe=`which 2>/dev/null $file`
[ $? -ne 0 ] && echo "$me: $file: No such executable" && exit 1
file=$exe
since=`stat -L --format '%Y' $file`
else
[ ! -e $file ] && echo "$me: $file: No such file" && exit 1
since=`stat --format '%Y' $file`
fi

printf "$file: "
get_age $since
done