This was originally posted by Bret Hubert nearly 6 months ago, but it’s saved me a LOT of time, since he’s rehashed, well, common sense:

“…
Additionally, our database interface needed to offer an extra feature: every once in a while a query comes along that we DO need to wait for, and because of coherency issues, such a query can only be executed once all queries ‘in flight’ have finished.
So we spent some time pondering this, and suddenly it dawned on me that many of the features we needed exactly match the semantics of the venerable UNIX ‘pipe’.
A pipe is normally used to communicate between two processes, as exemplified by this sample shell script command, which shows us the largest directories on a disk:
$ du | sort -n
The program ‘du’ generates a list of directories and their sizes, which is then fed to sort which outputs this in ascending order. However, nothing prohibits us from using a pipe to communicate with ourselves – and as such it might be a might fine conduit to pass database queries through to our database worker thread.
This has some very nice benefits. Pipes are incredibly efficient, since a lot of UNIX performance depends on them. Additionally, they implement sane blocking behaviour: if too much data is stuck in the pipe, because the other process does not take it out again quickly enough, the sending process automatically blocks. The operating system implements high and low water marks to make this (un)blocking happen efficiently.
Furthermore, pipes guarantee that data up to a certain size can either be written as a whole, or not written at all – making sure we don’t have to deal with partial messages.
Finally, pipes automatically detect when the process on the other end of them has gone away, or has closed its end of the pipe.
However, not all is good. In order to transmit something over a pipe, it must be serialised into bytes – we can’t transmit ready to use objects over them. Additionally, because pipes implement ‘stream’ behaviour, we need to delineate one message from the other, because the pipe itself does not say where a message begins and ends – unlike datagram sockets for example.
And this is the clever bit of our idea. As stated above, pipes are usually employed to transmit data from one process to the other. In our case, the pipe goes from one thread of execution to the other – within the same process, and thus within the same memory space. So we don’t need to send serialized objects at all, and can get away with transmitting pointers to objects. And the nice thing is, pointers all have the same (known) length – so we can do away with both delineation and serialisation.
Additionally, pointers are a lot smaller than most messages, which means we can stuff more messages in the same (fixed) size of the pipe buffer.
So, are we done now? Sadly no – we have the additional need to be able to ‘flush the pipe’ in order to perform synchronous queries that we do need to wait for.
This is where things get complicated, but for those who really want to know, I’ll explain it here. It took almost a day of hacking to get it right however, and I’m explaining it for my own benefit as much as for that of the reader, since I’m bound to forget the details otherwise.
If a synchronous query comes along, we need to flush the pipe, but UNIX offers no such ability. Once we’ve written something to a pipe, all the kernel guarantees us is that it will endeavour to deliver it, but there is no system call that allows us to wait for all data to actually be delivered.
So we need to find a way to signal a ‘write barrier’, and the obvious way to do so is to send a NULL pointer over the pipe, which tells the other end we want to perform a synchronous query. Once the worker thread has seen the NULL pointer, it unlocks the single controlling mutex (which is the return signal that says “got you -the pipe is empty”), and then waits for further pointers to arrive.
Meanwhile, the sending thread tries to lock that same mutex immediately after sending the NULL pointer, which blocks since the receiving thread normally holds the lock. Once the lock succeeds, this tells us the worker thread has indeed exhausted all queries that were in flight.
The sending thread now performs its synchronous database work, knowing the database is fully coherent with all queries it sent out previously, and also knowing the worker thread is not simultaneously accessing the connection – since it is instead waiting for a new pointer to arrive.
If our program now wants to perform further asynchronous queries it can simply transmit further pointers to the worker thread – which oddly enough does not need to retake the mutex. This is what caused us many hours of delay, because intuitively it seems obvious that once the sending thread is done, it must release the mutex so the worker thread can retake it.
As it turns out, doing so opens a whole world of nasty race conditions which allow synchronous queries to ‘jump the queue’ of asynchronous queries that are in flight and have not yet arrived.
So, the sequence is that the worker thread only unlocks the mutex, while the sending thread only locks it.
And this basically is it! So how much lines of code did we save by using the magic of UNIX pipes? The pipe handling code takes all of 90 lines, whereas the Distributor code of PowerDNS takes a round 300, even though it does not offer synchronous queries, does not automatically block if too many queries are outstanding, and most certainly couldn’t implement the sensible wakeup ability that UNIX pipes do offer.
Oh, and you might be wondering by now, did it help? Indeed it did – our program is now at least 20 times faster than it used to be, and there was much rejoicing.”

MaxMind’s mod_geoip directly inserted into your webserver would be the easiest for external/programmable GeoIP support.

It’d make more sense to check the browser’s language(s) of choice, than force a user of a region into a language they don’t want. Let Apache handle the language, itself, then just display the runtime code (if that’s what you want to do) independently with mod_geoip.

First, setup your supported languages, and priority in Apache:

AddLanguage en .en
AddLanguage fr .fr
AddLanguage es .es
AddLanguage de .de

Then, set your defaults you want to support in order of priority:

LanguagePriority en fr es de

Create multiple pages with the different languages embedded. “index.html” would be removed, and you would have “index.html.en”, “index.html.fr”, “index.html.es”, and “index.html.de” (This also works for .php, .shtml, etc.)

Now, GeoIP’s database for the country name database part, which almost mimmics the above, but uses a different format, ISO3166.

Here’s some tiny little throwaway GeoIP code. It displays those tiny flags in my sig. It has very little overhead with mod_geoip, marginal with the runtime PHP library. This is an old version without eTags (caching) support. It’d be smarter to cache these into RAM than to continually read them from the disk, if you have the choice. You may use this code, if you want.

<?php
// Simple little example utlity to display a small flag based upon GeoIP data.
// by Shawn Holwegner <shawn/at/holwegner/dot/com>
// You may reuse this code, if you want.  I stake no claims to it.
//
// This example supports both mod_geoip, and the external PHP API.
// If mod_geoip is installed:
  $country = "";
  // Do we have apache_note()?
  if (function_exists('apache_note'))
    $country = strtolower(apache_note("GEOIP_COUNTRY_CODE"));
  if (empty($country)) {
    // external MaxMind PHP support
    @require_once("./geoip.inc");
    $gi = geoip_open("./GeoIP.dat", GEOIP_STANDARD);
    $country = strtolower(geoip_country_code_by_addr($gi, $_SERVER["REMOTE_ADDR"
]));
    geoip_close($gi);
    if ($country) {
      header ("Pragma: no-cache");
      header("Expires: Mon, 26 Jul 1999 04:20:00 GMT");
      header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
      header('Cache-Control: no-store, no-cache, must-revalidate');
      header('Cache-Control: pre-check=0, post-check=0, max-age=0');
      header("Content-type: image/gif");
      if (file_exists('./'.$country.'.gif')) {
         readfile('./'.$country.'.gif');
      } else {
         // Generic 'empty' country banner.
         readfile("./00.gif");
      }
    }
  }
?>

I hope this information has been helpful as to easily, and properly implement GeoIP support. Stop forcing me to read Spanish when I’m in Latin America; I get enough of that when I’m in the states!

Long after the death of the ‘demoscene’ of the 90s, I stumble upon Ronald Jenkees. If he’s not demoscene, nothing is. Check this out, it starts out very Skaven, has a touch of Vogue in it, and ends up with a twist of Purple Motion:

Here’s one of his more “Hip-Hop” tracks:

You want it? Sure you do. Click here to get it.

Postfix: Ronald replied to me about my proposed demoscene influence:

“I loved demoscene before I knew there was a name for it. … Then just recently some commenters (you included) educated me on that. Whatta cool thing.”

What a down to earth guy.

Post-Postfix: I bought his CD and it’s worth every cent. Can’t wait for the next one!

This was annoying me. The KPowersave module could control my LCD's backlight, but the ACPI controls would not. Obviously, there is full hardware support, but the ACPI system isn't quite up to the task.

The ACPI scripts merely fake the keys when called, with a hard coded value. This, obviously, was not working.

So, I decided on a rather convoluted method. First, I ended up finding my actual brightness control device (there are several listed on my machine), by running the following as root (it will NOT work via sudo):

  %for n in /proc/acpi/video/**/LCD/brightness; do \
   echo "Trying $n..."; for fade in `seq 1 100`; do sleep \
   0.01s; echo -n "$fade" > $n; done; done

This will print the devices it finds, and attempt to set the LCD levels from 1 (nearly off) to 100 (full brightness). As different LCDs have different specifications, you can't just randomly assume a single number will work. I was being lazy, and although it didn't accept them all, it was still a neat effect.

I found that my LCD device was actually: /proc/acpi/video/VID1/LCD/brightness

Then, I made the world's ugliest parser to see what the available levels were, and to shift up, or down, according to the script. Since there are separate 'up' and 'down' scripts, I decided to be lazy. Have I mentioned yet how incredibly ugly this whole thing is? I wish there was a more bourne-ish portable way to deal with quasi-arrays.

Here's my new /etc/acpi/video_brightnessdown.sh:

#!/bin/sh
#Yeah, I got kind of lazy.  Arrays in Bourne SUCK.
DEVICE=/proc/acpi/video/VID1/LCD/brightness
#. /usr/share/acpi-support/key-constants
#acpi_fakekey $KEY_BRIGHTNESSDOWN
CURRENTLEVEL=`grep 'current:' $DEVICE | awk '{print $2}'`
if [ "x"$CURRENTLEVEL = "x0" ]; then
  CURRENTLEVEL=100
fi
SORTEDLEVELS=`grep 'levels:' $DEVICE | sed -e \
   s,levels:,,g -e 's,\s,\n,g' | sort -n | uniq | \
   grep -v '^$' | sed s,\n,\ ,g | xargs echo`
for levels in `echo $SORTEDLEVELS | sed 's,\n,\ ,g'`
do
    if [ $CURRENTLEVEL = $levels ]; then
      echo -n $LASTLEVEL > $DEVICE
      break
    fi
    LASTLEVEL=$levels
done
... and /etc/acpi/video_brightnessup.sh:

#!/bin/sh
#. /usr/share/acpi-support/key-constants
#acpi_fakekey $KEY_BRIGHTNESSUP
DEVICE=/proc/acpi/video/VID1/LCD/brightness
CURRENTLEVEL=`grep 'current:' $DEVICE | awk '{print $2}'`
if [ "x"$CURRENTLEVEL = "x0" ]; then
  CURRENTLEVEL=100
fi
SORTEDLEVELS=`grep 'levels:' $DEVICE | sed -e s,levels:,,g \
  -e 's,\s,\n,g' | sort -n -r | uniq | grep -v '^$' \
  | sed s,\n,\ ,g | xargs echo`
for levels in `echo $SORTEDLEVELS | sed 's,\n,\ ,g'`
do
    if [ $CURRENTLEVEL = $levels ]; then
      echo -n $LASTLEVEL > $DEVICE
      break
    fi
    LASTLEVEL=$levels
done

Remember to chmod your files, and chown them!

chmod 755 /etc/acpi/video_brightnessup.sh
chmod 755 /etc/acpi/video_brightnessdown.sh
chown root.root /etc/acpi/video_brightnessup.sh
chown root.root /etc/acpi/video_brightnessdown.sh
I hope these scripts work for you, and save you some of the headache I was experiencing!