Threading
Why it wasn't threadsafe. cross the road? did the chicken
Technorati Tags: coding
« January 2007 | Main | March 2007 »
Why it wasn't threadsafe. cross the road? did the chicken
Technorati Tags: coding
The Rhapsody website player now sports a shuffle (and repeat) button. Yay! Random new band I like thanks to a tip from a Rhapsody sysadmin: Explosions In The Sky.
Avoid plain use Module::Name in favor of either an empty import list, or a specific list of items to trample on the local namespace with:
use CGI; # expensive! use CGI (); # much better use POSIX; # slow and much trampling use POSIX qw(strftime); # just this subroutine
Limiting module imports saves time, and lessens the risk that two functions with the same name will be used. A quick review of the use statements will generally reveal exactly what has been imported, such as strftime in the example above. Should a new module version export more by default, the explicit import list will avoid any namespace changes to scripts.
Technorati Tags: Perl
Benchmarking use properly is tricky…
#!/usr/bin/perl -w use strict; use Benchmark qw(cmpthese); cmpthese( -5, { 'use-import' => sub { eval "use CGI;" }, 'use-empty' => sub { eval "use CGI ();" }, });
Cliff Stoll (author, The Cuckoo's Egg) sells Klein Bottles online. And now you know!
Technorati Tags: chess
parse-sudoers does not follow the sudoers BNF, though will tidy up the data, especially where unsorted users reside in sprawling multiline blocks.
$ cat input User_Alias SOME_USERS = finell, dobbs, bialy, \ garib, cavaluzzi, kubica, \ deutschman, noth, standford, mcelmurry $ parse-sudoers input User_Alias SOME_USERS = bialy, cavaluzzi,⏎ deutschman, dobbs, finell, garib, kubica,⏎ mcelmurry, noth, standford
Technorati Tags: Perl
Output from the following code may fail validation where a downstream system expects key:value pairs and does not support empty fields at the end of the record.
print "OK:foo:" . join(':', @key_value_pairs) . "\n"
If @key_value_pairs is empty, resulting in the unacceptable OK:foo:. Safer code would include this prefix as an argument to the join function:
my @OUTPUT_PREFIX = qw(OK foo); print join(':', @OUTPUT_PREFIX, @key_value_pairs) . "\n"
This way a proper colon delimited list is generated, or an empty string should both arrays be empty.
No, I haven’t been bitten by this gotcha. No, really!
Chess/Shogi take III. Shogi set arrived at work, but could not round up enough folks for a try at bughouse Shogi…
Technorati Tags: chess
kronsoon generates a crontab(5) compatible timestamp in the near future, optionally followed by a command, optionally preceded by a comment. Similar to what an at(1) job can do, though handy where a utility must run from cron(8) to replicate the state of another command normally run under cron.
The forum post how to test Daylight Saving Time settings for 2007 contains a script that tests daylight saving changes without altering the system time.
Like Y2K, the early daylight savings change this year gives management something to fuss over. I’m personally in favor of more gmtime(3) and less localtime(3) use, as a code review at work reveals many needless localtime uses. Unfortunately these uses will require a fair amount of work to convert to gmtime, especially where the data wanders off to other groups.
In addition to the HTTP status code, URL monitors must capture the request latency: a site may be responding, but slowly enough to impact customers. The following code outlines a URL monitor in Perl, using LWP::UserAgent to request the URL and Time::HiRes to measure latency:
#!/usr/bin/perl -w use strict; my $url = shift || die "Usage: $0 url\n"; use LWP::UserAgent (); use Time::HiRes qw(gettimeofday tv_interval); my %output; my $ua = LWP::UserAgent->new; my $start = [gettimeofday]; my $response = $ua->get($url); $output{latency} = sprintf '%.2f', tv_interval($start); $output{status} = $response->code; # TODO template %output as demanded by # the monitoring system for my $key ( keys %output ) { print "$key=$output{$key}\n"; }
Graph the HTTP status code along with the latency. This avoids the information loss produced by mapping the codes into arbitrary “good” or “bad” values. The alerting framework should handle translation of the code into an alert, as appropriate for the URL: >= 400 pages someone, while >= 300 only warns about the unexpected redirection response.
The latency graph provides clues into the problem: assuming a 200 HTTP status code in each case, a ledge at N seconds indicates a timeout of some sort (check for DNS problems), while a scattered graph points to network packet loss or similar load induced problem. Watch the average latency over time, then set an appropriate alert threshold, perhaps five seconds. Another option: alert should a “major” increase occur in the latency, perhaps one or two standard deviations above a moving average. This will catch sudden latency increases, but will fail to alert in the event latency slowly rises beyond the Service Level Agreement (SLA) threshold.


If possible, negotiate the SLA in advance, to ensure a proper solution can be developed. Also consider how far below the SLA alerts must be set, to allow triage before a system breaks SLA.
A single script can check multiple related URL as plugin for Nagios or comparable monitoring systems. Do not number the URL arguments in the output; instead, associate short aliases for each URL monitored. Numbered URL force the question “well, what URL is actually in error?” while aliases provide a hint while not exceeding any length limits on monitoring output. If the monitoring system allows, include the full URL in the output, so a reader can copy or click on the URL directly from the alarm message.
#!/usr/bin/perl -w use strict; die "Usage: $0 alias.url [.. alias.url]\n" unless @ARGV; use LWP::UserAgent (); use Time::HiRes qw(gettimeofday tv_interval); my @results; my $ua = LWP::UserAgent->new; for my $target (@ARGV) { my %output; ( $output{alias}, $output{url} ) = split /\./, $target, 2; my $start = [gettimeofday]; my $response = $ua->get( $output{url} ); $output{latency} = sprintf '%.2f', tv_interval($start); $output{status} = $response->code; push @results, \%output; } for my $result (@results) { print join( ':', map { $result->{$_} } qw(alias status latency) ), "\n"; }
If necessary, also setup content checks that ensure websites contain the expected content. A site may return 200 status codes within the SLA, but contain no data if a software bug or caching problem omits some or all of the page content.
Technorati Tags: Perl