Posts Tagged ‘network cache’

Following my earlier tests, I’ve got good hopes for Plack on Windows. To ramp it up from the hello world example I thought I’d try a simple network cache. HTTP isn’t obviously the best protocol for this purpose, but it’s widely used, presumably due to the existence of many robust servers (also maybe because people [including me of course!] can’t be bothered to check for short tcp reads/writes).

To make the example simple, I have (a) elided the actual call to retrieve the data and (b) put all of the code in one file. Obviously I wouldn’t recommend doing this in production but hopefully it will convey the intent.

# —

Most of my perl starts with a preamble that looks somewhat like this.

use 5.010;

use strict;
use warnings;

use POSIX;

get_data represents a call (to a database for example) that will take a while to complete.

sub get_data
    my $key = shift;
    sleep 5;
    return "[$key]";

get_cached_data is also very much simplified. Normally I’d expect to use something like the Cache::XXX modules.

sub get_cached_data
    my $key = shift;
    state %cache;

    if (! exists($cache{$key})) {
        $cache{$key} = get_data($key);

    return $cache{$key};

response wraps the PSGI response to make the example a bit cleaner. It obviously wouldn’t be appropriate if other http response types were returned.

sub response
    my $data = shift;

    return [
        ['Content-Type' => 'text/plain'],

Twiggy doesn’t log the information about the request by default in the same way as plackup does. There may be a flag to enable that (should look at the code) but for now I synthesise it from $env.

sub request_info
    my $env = shift;
    my $ts = POSIX::strftime('%d/%b/%Y %H:%M:%S', localtime(time()));

    return qq{$env->{REMOTE_ADDR} - - [$ts] }
         . qq{"$env->{REQUEST_METHOD} $env->{PATH_INFO} $env->{SERVER_PROTOCOL}" }
         . qq{"-" "$env->{HTTP_USER_AGENT}"};

And there should be nothing surprising in the main.

# -- main

my $app = sub {
    my $env = shift;

    # foreach my $key (keys %$env) {
    #     print "$key $env->{$key}\n";
    # }

    # Twiggy doesn't give the same request info as vanilla plack
    say request_info($env);

    # Could map METHOD/PATH to subroutine calls using a hash
    my $method = $env->{REQUEST_METHOD};
    my $path_info = $env->{PATH_INFO};

    my $start = time();
    my $response = response(get_cached_data($path_info));
    my $time = time() - $start;
    my $s = ($time == 1) ? '' : 's';
    say "Generating response took $time second$s";

    return $response;

Testing with firefox is a bit crufty, but I haven’t got around to adapting my test client yet.

$ twiggy --listen :8080 obj-cache.psgi - - [30/Mar/2010 21:24:47] "GET /someurl/ HTTP/1.1" "-" "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv: Gecko/20100316 Firefox/3.6.2 (.NET CLR 3.5.30729)"
Generating response took 5 seconds - - [30/Mar/2010 21:25:02] "GET /someurl/ HTTP/1.1" "-" "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv: Gecko/20100316 Firefox/3.6.2 (.NET CLR 3.5.30729)"
Generating response took 0 seconds # Yes, looks good!

Read Full Post »