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
_______________________________________________
maypole mailing list
maypole at lists.netthink.co.uk
http://lists.netthink.co.uk/listinfo/maypole
This archive was generated by hypermail 2.1.3 : Thu Feb 24 2005 - 22:25:56 GMT