Code

gitweb: Add support for FastCGI, using CGI::Fast
authorSam Vilain <sam.vilain@catalyst.net.nz>
Fri, 7 May 2010 12:54:05 +0000 (14:54 +0200)
committerJunio C Hamano <gitster@pobox.com>
Sun, 9 May 2010 05:26:52 +0000 (22:26 -0700)
Former run() subroutine got renamed to run_request().  The new run()
subroutine can run multiple requests at once if run as FastCGI script.

To run gitweb as FastCGI script you must specify '--fastcgi' / '-f'
command line option to gitweb, otherwise it runs as an ordinary CGI
script.

[jn: cherry picked from 56d7d436644ab296155a697552ea1345f2701620
 in http://utsl.gen.nz/gitweb/?p=gitweb which was originally based
 on v264 (2326acfa95ac86a53804ca8eeeb482c2f9265e34) by Kay Sievers;
 updated to reflect current gitweb code]

TODO: update 'gitweb/README' and/or 'gitweb/INSTALL' files.

Signed-off-by: Sam Vilain <sam.vilain@catalyst.net.nz>
Signed-off-by: Jakub Narebski <jnareb@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
gitweb/gitweb.perl

index 4a3632ab50add337493fbb0d4562917ed52d1e12..b044d18acaff0527a4da9a37f8587be955eb4f0f 100755 (executable)
@@ -999,7 +999,7 @@ sub dispatch {
        $actions{$action}->();
 }
 
-sub run {
+sub run_request {
        our $t0 = [Time::HiRes::gettimeofday()]
                if defined $t0;
 
@@ -1019,11 +1019,61 @@ sub run {
        configure_gitweb_features();
 
        dispatch();
+}
+
+our $is_last_request = sub { 1 };
+our ($pre_dispatch_hook, $post_dispatch_hook, $pre_listen_hook);
+our $CGI = 'CGI';
+our $cgi;
+sub evaluate_argv {
+       return unless (@ARGV);
+
+       require Getopt::Long;
+       Getopt::Long::GetOptions(
+               'fastcgi|fcgi|f' => sub {
+                       require CGI::Fast;
+                       our $CGI = 'CGI::Fast';
+
+                       my $request_number = 0;
+                       # let each child service 100 requests
+                       our $is_last_request = sub { ++$request_number > 100 };
+               },
+               'nproc|n=i' => sub {
+                       my ($arg, $val) = @_;
+                       return unless eval { require FCGI::ProcManager; 1; };
+                       my $proc_manager = FCGI::ProcManager->new({
+                               n_processes => $val,
+                       });
+                       our $pre_listen_hook    = sub { $proc_manager->pm_manage()        };
+                       our $pre_dispatch_hook  = sub { $proc_manager->pm_pre_dispatch()  };
+                       our $post_dispatch_hook = sub { $proc_manager->pm_post_dispatch() };
+               },
+       );
+}
+
+sub run {
+       evaluate_argv();
+
+       $pre_listen_hook->()
+               if $pre_listen_hook;
+
+ REQUEST:
+       while ($cgi = $CGI->new()) {
+               $pre_dispatch_hook->()
+                       if $pre_dispatch_hook;
+
+               run_request();
+
+               $pre_dispatch_hook->()
+                       if $post_dispatch_hook;
+
+               last REQUEST if ($is_last_request->());
+       }
 
  DONE_GITWEB:
        1;
 }
-our $cgi = CGI->new();
+
 run();
 
 ## ======================================================================