FCGI: Prozess nach Request beenden, falls belegter Speicher größer als konfigurierbar...
[kivitendo-erp.git] / dispatcher.fpl
1 #!/usr/bin/perl
2
3 use strict;
4
5 use FCGI;
6 use IO::File;
7 use SL::Dispatcher;
8 use SL::FCGIFixes;
9 use SL::LXDebug;
10
11 sub _parse_number_with_unit {
12   my ($number) = @_;
13
14   return undef   unless defined $number;
15   return $number unless $number =~ m{^ \s* (\d+) \s* ([kmg])b \s* $}xi;
16
17   my %factors = (K => 1024, M => 1024 * 1024, G => 1024 * 1024 * 1024);
18
19   return $1 * $factors{uc $2};
20 }
21
22 sub _memory_usage_is_too_high {
23   return undef unless $::lx_office_conf{system};
24
25   my %limits = (
26     rss  => _parse_number_with_unit($::lx_office_conf{system}->{memory_limit_rss}),
27     size => _parse_number_with_unit($::lx_office_conf{system}->{memory_limit_vsz}),
28   );
29
30   # $::lxdebug->dump(0, "limits", \%limits);
31
32   return undef unless $limits{rss} || $limits{vsz};
33
34   my %usage;
35
36   my $in = IO::File->new("/proc/$$/status", "r") or return undef;
37
38   while (<$in>) {
39     chomp;
40     $usage{lc $1} = _parse_number_with_unit($2) if m{^ vm(rss|size): \s* (\d+ \s* [kmg]b) \s* $}ix;
41   }
42
43   $in->close;
44
45   # $::lxdebug->dump(0, "usage", \%usage);
46
47   foreach my $type (keys %limits) {
48     next if !$limits{$type};
49     next if $limits{$type} >= ($usage{$type} // 0);
50
51     $::lxdebug->message(LXDebug::WARN(), "Exiting due to memory size limit reached for type '${type}': limit " . $limits{$type} . " bytes, usage " . $usage{$type} . " bytes");
52
53     return 1;
54   }
55
56   return 0;
57 }
58
59 our $dispatcher = SL::Dispatcher->new('FastCGI');
60 $dispatcher->pre_startup_setup;
61 SL::FCGIFixes::apply_fixes();
62 $dispatcher->pre_startup_checks;
63
64 my $request = FCGI::Request();
65 while ($request->Accept() >= 0) {
66   $dispatcher->handle_request($request);
67   exit if _memory_usage_is_too_high();
68 }
69
70 1;