[Maypole] re: Maypole::HTTPD

Dave Howorth Dave.Howorth@acm.org
Sat, 30 Oct 2004 12:45:58 +0100


Thanks for this code Simon and the great article. I can really recommend 
part of this idea - using a local embedded HTTP demon - because I've 
been doing that for the past year or so with one particular server. 
There are a number of benefits of this approach that stem from the demon 
being embedded:

Because it's embedded, the whole application is just a regular Perl 
program and you can debug it in the normal way with the debugger. This 
is much easier than debugging CGI programs or mod_perl.

Because the demon persists from one HTTP request to the next, so does 
the program state. This means you can carry out time-consuming 
initialization before the demon opens for service and keep the in-memory 
data structures around between requests without re-initializing. This is 
what motivated me to move to this style for my server; it takes about 20 
seconds to build a large in-memory linked data structure (directed 
cyclic graph) but this enables individual HTTP requests in the user's 
session to be answered extremely quickly.

There's a gotcha to beware of that arises from the same cause. Because 
CGI programs normally run through and exit you can be cavalier about the 
state of variables. So when I transformed my CGI script to use an 
embedded httpd, I found I had to go through and make sure that the state 
of variables at the end of each request was exactly what was required at 
the start of the next one. Mostly, this is just a matter of ensuring the 
correct scope for variables that should not persist from one request to 
the next. But if you're lazy like me, expect some strange symptoms!

Incidentally, it's still the same event-driven architecture as most GUI 
programs. There's an event loop and individual routines for each state. 
It's just that here the event loop is receiving HTTP requests instead of 
key and mouse events, or higher level widget events. About the only way 
out of this paradigm is to use both a language and a GUI toolkit that 
permit multi-threaded user interface rendering. Then each view object 
can have it's own flow of control and is able to maintain the interface 
state implicitly in program state instead of being forced to encapsulate 
it in data after every user interaction.

There's one detail in the httpd that ought to be corrected. HTTP and 
other internet protocols are quite explicit about end of line sequences; 
they should always be CR,LF. In Perl, the best way to do this is by 
writing \015\012 at the end of each string. The same goes for 
recognizing line endings when reading requests. It is NOT safe to use \n 
or even \r\n because there is Perl magic here. On 'classic' MacOS, Perl 
swaps the meaning of \r and \n in order to fit in with the operating 
system's conventions. I guess you were developing on OSX, Simon :)

So I can definitely recommend this approach when circumstances are 
right. It's great to have a Maypole version of the httpd; I may well use 
that sometime in the future, but it will be a while so don't let me stop 
anybody else releasing it :)

The other part of the article, about packaging up a Perl program as a 
single executable, was pure gold dust. I will definitely use that as 
well. Thanks very much :)

Cheers, Dave