PageRenderTime 59ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/modules/throttle.pl

https://repo.or.cz/Orgmuse.git
Perl | 80 lines | 43 code | 11 blank | 26 comment | 2 complexity | 1ae1ebc2649c50b387cd776758f8d893 MD5 | raw file
  1. # Copyright (C) 2004, 2006 Alex Schroeder <alex@emacswiki.org>
  2. # 2004 Sebastian Blatt <sblatt@havens.de>
  3. #
  4. # This program is free software; you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License as published by
  6. # the Free Software Foundation; either version 2 of the License, or
  7. # (at your option) any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public License
  15. # along with this program; if not, write to the
  16. # Free Software Foundation, Inc.
  17. # 59 Temple Place, Suite 330
  18. # Boston, MA 02111-1307 USA
  19. # Limits the number of parallel Oddmuse instances to
  20. # $InstanceThrottleLimit by keeping track of the process ids in
  21. # $InstanceThrottleDir
  22. $ModulesDescription .= '<p><a href="http://git.savannah.gnu.org/cgit/oddmuse.git/tree/modules/throttle.pl">throttle.pl</a>, see <a href="http://www.oddmuse.org/cgi-bin/oddmuse/Limit_Number_Of_Instances_Running">Limit Number Of Instances Running</a></p>';
  23. use File::Glob ':glob';
  24. use vars qw($InstanceThrottleDir $InstanceThrottleLimit);
  25. $InstanceThrottleDir = $DataDir."/pids"; # directory for pid files
  26. $InstanceThrottleLimit = 2; # maximum number of parallel processes
  27. *OldDoSurgeProtection = *DoSurgeProtection;
  28. *DoSurgeProtection = *NewDoSurgeProtection;
  29. *OldDoBrowseRequest = *DoBrowseRequest;
  30. *DoBrowseRequest = *NewDoBrowseRequest;
  31. sub NewDoSurgeProtection {
  32. DoInstanceThrottle();
  33. CreatePidFile();
  34. OldDoSurgeProtection();
  35. }
  36. sub NewDoBrowseRequest {
  37. OldDoBrowseRequest();
  38. RemovePidFile();
  39. }
  40. # limit the script to a maximum of $InstanceThrottleLimit instances
  41. sub DoInstanceThrottle {
  42. my @pids = bsd_glob($InstanceThrottleDir."/*");
  43. # Go over all pids: validate each pid by sending signal 0, unlink
  44. # pidfile if pid does not exist and return 0. Count the number of
  45. # zeros (= removed files = zombies) with grep.
  46. my $zombies = grep /^0$/,
  47. (map {/(\d+)$/ and kill 0,$1 or unlink and 0} @pids);
  48. if (scalar(@pids)-$zombies >= $InstanceThrottleLimit) {
  49. ReportError(Ts('Too many instances. Only %s allowed.',
  50. $InstanceThrottleLimit),
  51. '503 Service Unavailable',
  52. undef,
  53. $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.')));
  54. }
  55. }
  56. sub CreatePidFile {
  57. CreateDir($InstanceThrottleDir);
  58. my $data = $q->request_method . ' ' . $q->url(-path_info=>1) . "\n";
  59. foreach my $param ($q->param) {
  60. next if $param eq 'pwd';
  61. $data .= "Param " . $param . "=" . $q->param($param) . "\n";
  62. }
  63. WriteStringToFile("$InstanceThrottleDir/$$", $data);
  64. }
  65. sub RemovePidFile {
  66. my $file = "$InstanceThrottleDir/$$";
  67. # not fatal
  68. unlink $file;
  69. }