2006-03-03 15:52:54 +00:00
# Copyright (C) 2004, 2006 Alex Schroeder <alex@emacswiki.org>
2004-07-16 00:40:42 +00:00
# 2004 Sebastian Blatt <sblatt@havens.de>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the
# Free Software Foundation, Inc.
# 59 Temple Place, Suite 330
# Boston, MA 02111-1307 USA
# Limits the number of parallel Oddmuse instances to
# $InstanceThrottleLimit by keeping track of the process ids in
# $InstanceThrottleDir
2006-10-21 18:51:40 +00:00
$ ModulesDescription . = '<p>$Id: throttle.pl,v 1.6 2006/10/21 18:51:40 as Exp $</p>' ;
2004-07-16 00:40:42 +00:00
use vars qw( $InstanceThrottleDir $InstanceThrottleLimit ) ;
$ InstanceThrottleDir = $ DataDir . "/pids" ; # directory for pid files
$ InstanceThrottleLimit = 2 ; # maximum number of parallel processes
* OldDoSurgeProtection = * DoSurgeProtection ;
* DoSurgeProtection = * NewDoSurgeProtection ;
* OldDoBrowseRequest = * DoBrowseRequest ;
* DoBrowseRequest = * NewDoBrowseRequest ;
sub NewDoSurgeProtection {
DoInstanceThrottle ( ) ;
CreatePidFile ( ) ;
OldDoSurgeProtection ( ) ;
}
sub NewDoBrowseRequest {
OldDoBrowseRequest ( ) ;
RemovePidFile ( ) ;
}
# limit the script to a maximum of $InstanceThrottleLimit instances
sub DoInstanceThrottle {
my @ pids = glob ( $ InstanceThrottleDir . "/*" ) ;
# Go over all pids: validate each pid by sending signal 0, unlink
# pidfile if pid does not exist and return 0. Count the number of
# zeros (= removed files = zombies) with grep.
my $ zombies = grep /^0$/ ,
( map { /(\d+)$/ and kill 0 , $ 1 or unlink and 0 } @ pids ) ;
if ( scalar ( @ pids ) - $ zombies >= $ InstanceThrottleLimit ) {
2006-09-07 17:44:02 +00:00
ReportError ( Ts ( 'Too many instances. Only %s allowed.' ,
$ InstanceThrottleLimit ) ,
'503 Service Unavailable' ,
undef ,
$ q - > p ( T ( 'Please try again later. Perhaps somebody is running maintenance or doing a long search. Unfortunately the site has limited resources, and so we must ask you for a bit of patience.' ) ) ) ;
2004-07-16 00:40:42 +00:00
}
}
sub CreatePidFile {
CreateDir ( $ InstanceThrottleDir ) ;
2006-03-03 15:51:48 +00:00
my $ data = $ q - > request_method . ' ' . $ q - > url ( - path_info = > 1 ) . "\n" ;
foreach my $ param ( $ q - > param ) {
next if $ param eq 'pwd' ;
$ data . = "Param " . $ param . "=" . $ q - > param ( $ param ) . "\n" ;
}
WriteStringToFile ( "$InstanceThrottleDir/$$" , $ data ) ;
2004-07-16 00:40:42 +00:00
}
sub RemovePidFile {
my $ file = "$InstanceThrottleDir/$$" ;
2006-10-21 18:51:40 +00:00
# not fatal
unlink $ file ;
2004-07-16 00:40:42 +00:00
}