Apache::Backhand - Bridge between mod_backhand and mod_perl


 (in httpd.conf)
 PerlModule Apache::Backhand
 BackhandFromSO libexec/ byPerl Package::function

 sub function {
     my ($r, $s)   = @_;
     my (@servers) = @{$s};
     my $serverstats     = Apache::Backhand::load_serverstats();
     my $personal_arriba = Apache::Backhand::load_personal_arriba();

     # modify @servers...

 (the following constants are also provided...)


Apache::Backhand ties mod_perl together with mod_backhand, in two major ways. First, the Apache::Backhand module itself provides access to the global and shared state information provided by mod_backhand (most notably serverstats). Second, the byPerl C function (which is not part of the Apache::Backhand module, but is distributed together with it) allows you to write candidacy functions in Perl.

Apache::Backhand will crash your perl interpreter if you attempt to load it into a perl binary which isn't also part of apache, with both mod_perl and mod_backhand loaded. You'll get 'unresolved symbol' errors, or whatever their equivalent is on your system. This may seem obvious, but it has a less obvious side effect, which is that you cannot load Apache::Backhand until *after* mod_backhand is loaded. That is, the 'PerlModule Apache::Backhand' line must come after 'LoadModule backhand_module libexec/'.

Here are the two major functions provided by Apache::Backhand:


This function returns a reference to an array of MAXSERVERS references to hashes, the keys of which are:


Last modification time of this stat structure (the last time we heard from the server - used to decide if the server is alive)


Speed of the server


Number of available apache servers


Number of running apache servers


Load average (multiplied by 1000)


The supremim integral power of 2 of the load seen thus far


CPU idle time (multiplied by 1000)


Number of CPU


Total memory in bytes


Available memory in bytes


Number of requests backhanded


Averages time (in milliseconds) to serve a backhanded request

This structure sounds worse than it is. It's really quite simple to use:

  foreach my $server ($serverstats) {
      print $server->{'mtime'}, "\n";
      $server->{'load'} += 1;

Note that each of the elements of the hashes is magically tied directly (for both reads and writes) into the shared memory segment where serverstats resides. You can call load_serverstats() once, and use the returned structure as much as you want - it will always reflect the contents of the underlying shared structure. This has one drawback, however, which is that you cannot call load_serverstats() until after the shared memory segment has been created and attached. I recommend a PerlChildInit handler to do load_serverstats() into a global variable.


This function returns a reference to a scalar variable which is magically tied to the global mod_backhand_personal_arriba integer. This contains the arriba speed of the local machine.


As explained above, you cannot PerlModule or use() or require() Apache::Backhand until *after* mod_backhand (and mod_perl, of course) are linked into the server.

As explained above, you cannot call load_serverstats() until *after* the shared memory segment has been created and attached. The best place to do this is the child init phase.

It's easy to make mod_backhand coredump by doing Bad Things to serverstats (e.g. 'foreach (@{$serverstats}) { $_->{'mtime'} = time() }'...) Even though I've provided the magic to make serverstats writeable, this should be treated with care.

There is necessarily going to be a small amount of overhead when calling perl candidacy functions. I highly recommend calling byAge *before* calling any perl candidacy functions, because converting the server list into a perl array and back again is one of the most expensive operations byPerl has to perform, and byAge tends to knock out a lot of unnecessary work.


Hopefully none.


J. David Lowe,