Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Re: Re: multithreaded web application server in perl

by hackmare (Pilgrim)
on Dec 09, 2002 at 19:08 UTC ( [id://218623]=note: print w/replies, xml ) Need Help??


in reply to Re: multithreaded web application server in perl
in thread multithreaded web application server in perl

When failings of Perl are enumerated as a reason not to use it, on top of the list you often find the dependency on mod_perl, and the fact that you run all the mod_perl as the same user and that all the mod_perl jobs running share the same memory space(or something like that). Of course, second is the fact that you don't use mod_perl and therefore have no state and run slowly.

In short, while mod_perl is handy to have for binding to Apache, it is also a liability inasmuch as that it can bring down an entire website if something goes Very Wrong. And not using it is often the Kiss Of Death.

I have never used fast_cgi, and therefore can not comment on it.

After Perl's problems with mod_perl, the next attack on perl applications is the use of the cgi interface. As a matter of fact, the demo site above was designed to client specification that the url be path based and not cgi-like. I mean, it's so polarized that lots of us end up faking it by using Apache's mod_rewrite ore equivalent.

There's no denying the weaknesses of building your own server from the ground up, and I am sure many people see it as blasphemy, given Apache's excellent capabilities.

However, I have found that Apache and Perl don't support my needs for bidirectional interaction such as n-user games through the browser using SVG due to the overhead Apache imposes on the whole process. I do much better keeping everything in the base thread's context, minimizing IPC comms and DB interaction. It allows me to have player 1 see the actions of player 2 without relying on an update and 2 selects on a database, which kills performance (I typically need better than 1 connection per second per player for n-user arcade-type scenarios)

With HTTP::Daemon, and Net::SSLeasy you can generate nice solid connections, maintain state very tightly with a minimum of third-party help from Apache, and keep everything tightly connected within a single instance. The performance is much higher than anything I've achieved with mod_perl and a database.

And I have found that web applications are very specific in their IO and functionality requirements and very much like the idea of a stand-alone system that does not require anything other than itself to run. Simply in matters of reduced dependencies and simplified configuration, this is a huge work saver for me.

IMHO, Maybe it is time to take a look at the important features of Java (such as the servlet) and take a lesson from them.

And it was really not much effort. Implementing the threaded listener takes about 75 lines. The security manips take about 50 lines, and the application data take about 400 lines total. I'll pay 125 lines in headache (especially if it is always the same) to get rid of the 99% of Apache I don't need. And if I want a proxy to handle the port 80 connection then I just have to put in a handler for it. So far I think it's a good model that I can't touch with mod_perl. Althoough maybe I need to take another at fast_cgi.

Hackmare

Replies are listed 'Best First'.
Re: Re: Re: multithreaded web application server in perl
by perrin (Chancellor) on Dec 09, 2002 at 19:38 UTC
    All of the modern approaches to web development (Java servlets, PHP) have the same issues around possibly crashing the server that mod_perl does, because they all run the application code as part of the application server process. Even if you do write something that crashes, it only crashes the current process, not the whole server. Correct use of mod_perl involves separating the serving of static images and HTML from the dynamic mod_perl part (using a reverse proxy), so there is no possibility of breaking the non-mod_perl sections of the site.

    Using the CGI interface is a bad idea when you have the option of using something with better performance, but using path info vs. query args has nothing to do with the CGI interface. You can use path info from a CGI, even without mod_rewrite. Moreover, having support for legacy CGI in a server doesn't hurt any applications that aren't using CGI.

    You don't need to use a database to share data between mod_perl processes. You can use something like IPC::MM or MLDBM::Sync and get hundreds of read/write ops per second. I suspect it will scale better than the threaded HTTP::Daemon approach you're using. (What are you using exactly? HTTP::Daemon is not threaded.)

      Here is the main program I'm working with right now... It's incomplete but shows the backbone minus the irrelevant business content...

      use strict; use HTTP::Daemon; use HTTP::Response; use HTTP::Status; use BusinessLogic; use threads; my %opt = (); getopt('sx', \%opt); # -i, input file name [-t template name], valu +es in %opts. unless (defined $opt{s} ) { print STDOUT "\nUsage: ./orgserver -s datasourcename [-x xmloutput +flatfile]\n\n"; exit 0; } unless (-r $opt{s}) {print "Unable to read $opt{s}"} if ($opt{x}) {unless (-w $opt{x}) {print "Unable to write to $opt{w}"} +;exit 0} $| = 1; my $xmlfile = "OrgTree.xml"; my $xmlflatfile = $opt{'x'} || "FlatOrgFile.xml"; my $sourcefile = $opt{'s'} || 'data/infile-big.txt'; my $E = BusinessLogic->new({ sourcefile=>$sourcefile, xmlfile=>$xmlfile, xmlflatfile=>$xmlflatfile }); $E->writeLog(99,"new Model tree and Daemon created"); #create the HTTP::Daemon instance my $d = new HTTP::Daemon LocalAddr => $E->{server}->{hostname}, LocalPort=>$E->{server}->{url}; $| = 1; #should be familiar... many parts based on webserver in 100 lines by C +orion http://www.perlmonks.org/index.pl?node_id=116767 (from what I r +emember) print "Please contact me at: <URL: ", $d->url, " >\n"; for (;;) { $DB::single = 2; my $connect = $d->accept; print "We got a request '$connect'!\n"; my $thread = threads->new(\&connection,$connect,$E); $thread->detach; print "have detached from this connection\n"; } sub connection { my $c = shift; my $E = shift; print "We are starting a new connection thread with connection '$c'\n"; print "listening for request\n"; while (my $r = $c->get_request) { print "We got a request\n"; #ignore all but GET requests if ($r->method eq 'GET') { $E->{method} = $r->method; $E->regen(); $E->writeLog(99,"\n\n\n--------n\n\n"); $E->writeLog(8,"Incoming GET Request Content",$E->{request +}); my $path = $r->url->path; print "We are handling path request $path\n"; my $command = $E->securePath($path); #handle the command passed to us in the GET an +d generates the output headers and body my $ref = $E->run( +) || $E->writeLog(99,"Error processing $command! +",$!); $E->writeLog(8,'business logic finished'); my $response = new HTTP::Response( 404,undef,undef,"404 - +Not found." ); foreach my $key ( keys %{$E->{response}->{header}} ) { $response->header( $key=>$E->{response}->{header}->{$ke +y} ) } $response->content($E->{response}->{content}); $response->code($E->{response}->{code}); $c->send_response($response); } else { # go away! $c->send_error(RC_FORBIDDEN); } $E->regen(); } print "Closing connection '$c'"; $c->close; undef($c); }

      hackmare
      roasp.com

        It is very cool that Perl threads have come far enough for this to work now. It will soon be possible to do this without the need to write your own web server code by using mod_perl 2 with Apache 2 in multi-threaded mode. In fact you can do it right now, but there are CPAN modules (mostly ones that use XS) which will have problems with a threaded environment at this point.
(jeffa) 3Re: multithreaded web application server in perl
by jeffa (Bishop) on Dec 09, 2002 at 20:46 UTC
    "Maybe it is time to take a look at the important features of Java (such as the servlet) and take a lesson from them."

    Have you looked at POE yet? How about Wombat? (a servlet engine for Perl)

    Update: PodMaster asked me to write up something on Wombat. I have two finals this week, so i'll start next week sometime. :)

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    

      Yes, took a look at POE.. Very promising. Definitely going to be the source of lots of interesting things I think. I thought of trying this with Poe, but thought of the idea of My Own Webserver as too tauntalizing to pass up.

      I havent tried wombat, but remember reading up on it some time last year or early this year. Is it ripe yet (ie is it functional yet and used in big business environments)?

      hackmare

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://218623]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (5)
As of 2024-03-29 10:16 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found