Webserver Golf
Whenever I do anything new with web development I always remind myself to record it somewhere for future reference and for use by others - and, selfishly, to get their feedback. So after years of (not) doing that (un)successfully, I finally opened a techie blog.
My current project is 'Webserver Golf' - if you don't know, 'Golf' refers to a game or competition where you `succeed` by reducing your score as low as possible. It annoys me that this kind-of-endeavour is always referred to as Golf, as I truly despise the game; a game so dull Volkswagen felt motivated to name a car after it. Any suggestions gratefully accepted.
The rules of Webserver Golf to start with the `usual` (or my normal) web apparatus and see if I can speed it up. My general starting setup is MySql, Apache2, Template Toolkit (or html template) and mod_perl for perl modules. The game does not include any other tools that you may use such as cpan, cpanm, but does include replacements for CGI, MySQL, Template Engines and naturally any use of web servers (including software such as PSGI).
The project must utilise all of these:
1. A `recognised` db of any sort, constructed as you see fit (from which we must pull the text 'hello world').
2. A perl Module or framework.
3 A template engine (which inserts the text 'hello world' extracted from the db, through layer 2)
4 Outputs a html document saying 'hello world'.
I don't care about html/xhtml/html5 well formedness.
The final outcome should be a timed race against each setup on a single machine working to localhost. The winner being the quickest.
My first move will be Mongo, Dancer, template toolkit (possibly Tenjin).
Any suggestions?
Paul @paulmc000
Not a very clear spec ;-)
but, I'll give it a go judging by what I think you mean.
Golf in Perl usually means doing something in the fewest possible chars, but I don't think that is what you want, so, I've made it a *little* verbose :-)
First, the 'database', in a file called 'datafile' with template items one per line
----------
HELLO:hello
WORLD:world
----------
Next the DB engine to read the db and format into Perl (Calls the get_data sub which gets passed the filename)
--------------
use strict;
use warnings;
package MiniDB;
sub get_data{
my $data;
open my $fh, shift or die $!;
for(){
chomp;
my($k,$v) = split ':';
$data->{$k} = $v;
}
$data;
}
1;
----------------
Next the *simple* Template engine in MiniHTMLTemplate.pm
-----------------
package MiniHTMLTemplate;
use strict;
use warnings;
sub new{
my ($type, $args) = @_;
bless {p => {}, doc =>"", filename => $args->{filename}}, $type;
}
sub params{
my ($s, $p) = @_;
$s->{p} = $p;
}
sub output{
my $s = shift;
open my $tmpl, $s->{filename};
{$/ = undef; $s->{doc} = };
for(keys %{$s->{p}}){$s->{doc} =~ s//$s->{p}{$_}/};
$s->{doc};
}
1;
-------------------
Next a template which will be used by the engine
----------------
, !
-----------------
And finally the app itself which will listen on $listensocket and deliver the page. set it to a free socket if 3999 is in use. point a browser at localhost:3999 (or whatever socket you use)
-------------------
#!/usr/bin/perl
use strict;
use warnings;
use MiniDB;
use MiniHTMLTemplate;
use IO::Socket;
my $listensocket = 3999;
my $data = MiniDB::get_data('datafile');
my $tmpl = MiniHTMLTemplate->new({filename => 'template.tmpl'});
$tmpl->params($data);
my $body = $tmpl->output;
my $size = length $body;
my $headers = "HTTP/1.0 200 OK\nContent-Type: text/html\nContent-Length: $size\n\n";
my $sock = new IO::Socket::INET (
LocalPort => $listensocket,
Listen => 5,
Reuse => 1
)
or die "Could not connect: $!";
while (my $new_sock = $sock->accept ()){
my $pid = fork ();
die "Cannot fork: $!" unless defined ($pid);
if ($pid == 0) {
print $new_sock $headers, $body;
close $new_sock;
}
}
----------------
If this isn't what you're looking for, hopefully something will be of interest :-)
I've wrapped it all in code tags hopeing it will protect the format, especially the template. I hope it works :-)
Hmm. code tags didn't work, by the look of it :-)
"Golf, as I truly despise the game; a game so dull Volkswagen felt motivated to name a car after it."
Wrong. The Golf name is derived from the German word for Gulf Stream — and the period in its history when VW named vehicles after prominent winds, including also the Passat (after the German word for Trade wind), Jetta (after the Jet stream), Bora (after Bora) and Scirocco (after Sirocco).
Yes! It is very important!!