You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl-cvs@perl.apache.org by au...@apache.org on 2006/07/05 20:04:30 UTC
svn commit: r419300 - in /perl/Apache-SizeLimit/trunk:
lib/Apache/SizeLimit.pm t/response/TestApache/basic.pm
t/response/TestApache/deprecated.pm
Author: autarch
Date: Wed Jul 5 11:04:30 2006
New Revision: 419300
URL: http://svn.apache.org/viewvc?rev=419300&view=rev
Log:
Lots of work on the core code, docs, and tests.
* Added a new OO API for configuring Apache::SizeLimit with better
(IMO) names for the methods, such as
Apache::SizeLimit->set_max_process_size().
* Added a new method Apache::SizeLimit->add_cleanup_handler().
* Lots of code refactoring to make the module more testable.
* Docs for all the new bits, plus re-ordering of existing docs to put
the API first, then platform stuff, then other bits.
* Tests for the new and deprecated APIs which actually test something
useful :)
* Basically un-documented the $USE_SMAPS global, except for a
reference in the "DEPRECATED APIS" section. Encouraging people to
explicitly tell the module to use bad data is not a good idea. Based
on discussion with Perrin.
Added:
perl/Apache-SizeLimit/trunk/t/response/TestApache/deprecated.pm
Modified:
perl/Apache-SizeLimit/trunk/lib/Apache/SizeLimit.pm
perl/Apache-SizeLimit/trunk/t/response/TestApache/basic.pm
Modified: perl/Apache-SizeLimit/trunk/lib/Apache/SizeLimit.pm
URL: http://svn.apache.org/viewvc/perl/Apache-SizeLimit/trunk/lib/Apache/SizeLimit.pm?rev=419300&r1=419299&r2=419300&view=diff
==============================================================================
--- perl/Apache-SizeLimit/trunk/lib/Apache/SizeLimit.pm (original)
+++ perl/Apache-SizeLimit/trunk/lib/Apache/SizeLimit.pm Wed Jul 5 11:04:30 2006
@@ -20,65 +20,189 @@
use strict;
use vars qw(
$VERSION
- $MAX_PROCESS_SIZE
$REQUEST_COUNT
- $CHECK_EVERY_N_REQUESTS
- $MIN_SHARE_SIZE
- $MAX_UNSHARED_SIZE
$START_TIME
- $IS_WIN32
$USE_SMAPS
);
-$VERSION = '0.9';
-$CHECK_EVERY_N_REQUESTS = 1;
+$VERSION = '0.9';
+
+__PACKAGE__->set_check_interval(1);
+
$REQUEST_COUNT = 1;
-$MAX_PROCESS_SIZE = 0;
-$MIN_SHARE_SIZE = 0;
-$MAX_UNSHARED_SIZE = 0;
-$IS_WIN32 = 0;
$USE_SMAPS = 1;
-BEGIN {
+use constant IS_WIN32 => $Config{'osname'} eq 'MSWin32' ? 1 : 0;
+
+
+use vars qw( $MAX_PROCESS_SIZE );
+sub set_max_process_size {
+ my $class = shift;
+
+ $MAX_PROCESS_SIZE = shift;
+}
+
+use vars qw( $MAX_UNSHARED_SIZE );
+sub set_max_unshared_size {
+ my $class = shift;
+
+ $MAX_UNSHARED_SIZE = shift;
+}
+
+use vars qw( $MIN_SHARE_SIZE );
+sub set_min_shared_size {
+ my $class = shift;
+
+ $MIN_SHARE_SIZE = shift;
+}
+
+use vars qw( $CHECK_EVERY_N_REQUESTS );
+sub set_check_interval {
+ my $class = shift;
+
+ $CHECK_EVERY_N_REQUESTS = shift;
+}
+
+sub handler ($$) {
+ my $class = shift;
+ my $r = shift || Apache->request;
+
+ return DECLINED unless $r->is_main();
+
+ # we want to operate in a cleanup handler
+ if ( $r->current_callback eq 'PerlCleanupHandler' ) {
+ return $class->_exit_if_too_big($r);
+ }
+ else {
+ $class->add_cleanup_handler($r);
+ }
+
+ return DECLINED;
+}
+
+sub add_cleanup_handler {
+ my $class = shift;
+ my $r = shift || Apache->request;
+
+ return unless $r;
+ return if $r->pnotes('size_limit_cleanup');
+
+ # This used to use $r->post_connection but there's no good way to
+ # test it, since apparently it does not push a handler onto the
+ # PerlCleanupHandler phase. That means that there's no way to use
+ # $r->get_handlers() to check the results of calling this method.
+ $r->push_handlers( 'PerlCleanupHandler',
+ sub { $class->_exit_if_too_big() } );
+ $r->pnotes( size_limit_cleanup => 1 );
+}
+
+sub _exit_if_too_big {
+ my $class = shift;
+ my $r = shift;
+
+ return DECLINED
+ if ( $CHECK_EVERY_N_REQUESTS
+ && ( $REQUEST_COUNT++ % $CHECK_EVERY_N_REQUESTS ) );
+
+ $START_TIME ||= time;
+
+ if ( $class->_limits_are_exceeded() ) {
+ my ( $size, $share, $unshared ) = $class->_check_size();
+
+ if ( IS_WIN32 || $class->real_getppid() > 1 ) {
+ # this is a child httpd
+ my $e = time - $START_TIME;
+ my $msg = "httpd process too big, exiting at SIZE=$size KB";
+ $msg .= " SHARE=$share KB UNSHARED=$unshared" if ($share);
+ $msg .= " REQUESTS=$REQUEST_COUNT LIFETIME=$e seconds";
+ $class->_error_log($msg);
+
+ if (IS_WIN32) {
+ # child_terminate() is disabled in win32 Apache
+ CORE::exit(-2);
+ }
+ else {
+ $r->child_terminate();
+ }
+ }
+ else {
+ # this is the main httpd, whose parent is init?
+ my $msg = "main process too big, SIZE=$size KB ";
+ $msg .= " SHARE=$share KB" if ($share);
+ $class->_error_log($msg);
+ }
+ }
+ return OK;
+}
+
+# REVIEW - Why doesn't this use $r->warn or some other
+# Apache/Apache::Log API?
+sub _error_log {
+ my $class = shift;
+
+ print STDERR "[", scalar( localtime(time) ),
+ "] ($$) Apache::SizeLimit @_\n";
+}
+
+sub _limits_are_exceeded {
+ my $class = shift;
+
+ my ( $size, $share, $unshared ) = $class->_check_size();
+
+ return 1 if $MAX_PROCESS_SIZE && $size > $MAX_PROCESS_SIZE;
+
+ return 0 unless $share;
+
+ return 1 if $MIN_SHARE_SIZE && $share < $MIN_SHARE_SIZE;
+
+ return 1 if $MAX_UNSHARED_SIZE && $unshared > $MAX_UNSHARED_SIZE;
- # decide at compile time how to check for a process' memory size.
+ return 0;
+}
+
+sub _check_size {
+ my ( $size, $share ) = _platform_check_size();
+
+ return ( $size, $share, $size - $share );
+}
+
+sub _load {
+ my $mod = shift;
+
+ eval "require $mod"
+ or die "You must install $mod for Apache::SizeLimit to work on your platform.";
+}
+
+BEGIN {
if ( $Config{'osname'} eq 'solaris'
&& $Config{'osvers'} >= 2.6 ) {
- *check_size = \&_solaris_2_6_size_check;
+ *_platform_check_size = \&_solaris_2_6_size_check;
*real_getppid = \&_perl_getppid;
}
elsif ( $Config{'osname'} eq 'linux' ) {
- eval { require Linux::Pid }
- or die "You must install Linux::Pid for Apache::SizeLimit to work on your platform.";
+ _load('Linux::Pid');
*real_getppid = \&_linux_getppid;
if ( eval { require Linux::Smaps } && Linux::Smaps->new($$) ) {
- *check_size = \&_linux_smaps_size_check;
+ *_platform_check_size = \&_linux_smaps_size_check;
}
else {
$USE_SMAPS = 0;
- *check_size = \&_linux_size_check;
+ *_platform_check_size = \&_linux_size_check;
}
}
elsif ( $Config{'osname'} =~ /(?:bsd|aix|darwin)/i ) {
-
# will getrusage work on all BSDs? I should hope so.
- eval "require BSD::Resource;"
- or die
- "You must install BSD::Resource for Apache::SizeLimit to work on your platform.";
+ _load('BSD::Resource');
- *check_size = \&_bsd_size_check;
+ *_platform_check_size = \&_bsd_size_check;
*real_getppid = \&_perl_getppid;
}
- elsif ( $Config{'osname'} eq 'MSWin32' ) {
- eval { require Win32::API }
- or die
- "You must install Win32::API for Apache::SizeLimit to work on your platform.";
+ elsif (IS_WIN32) {
+ _load('Win32::API');
- $IS_WIN32 = 1;
-
- *check_size = \&_win32_size_check;
+ *_platform_check_size = \&_win32_size_check;
*real_getppid = \&_perl_getppid;
}
else {
@@ -87,13 +211,17 @@
}
sub _linux_smaps_size_check {
- return _linux_size_check() unless $USE_SMAPS;
+ my $class = shift;
+
+ return $class->_linux_size_check() unless $USE_SMAPS;
my $s = Linux::Smaps->new($$)->all;
return ($s->size, $s->shared_clean + $s->shared_dirty);
}
sub _linux_size_check {
+ my $class = shift;
+
my ( $size, $resident, $share ) = ( 0, 0, 0 );
if ( open my $fh, '<', '/proc/self/statm' ) {
@@ -101,7 +229,7 @@
close $fh;
}
else {
- _error_log("Fatal Error: couldn't access /proc/self/status");
+ $class->_error_log("Fatal Error: couldn't access /proc/self/status");
}
# linux on intel x86 has 4KB page size...
@@ -109,8 +237,10 @@
}
sub _solaris_2_6_size_check {
+ my $class = shift;
+
my $size = -s "/proc/self/as"
- or _error_log("Fatal Error: /proc/self/as doesn't exist or is empty");
+ or $class->_error_log("Fatal Error: /proc/self/as doesn't exist or is empty");
$size = int( $size / 1024 );
# return 0 for share, to avoid undef warnings
@@ -122,6 +252,8 @@
}
sub _win32_size_check {
+ my $class = shift;
+
# get handle on current process
my $get_current_process = Win32::API->new(
'kernel32',
@@ -168,98 +300,34 @@
sub _perl_getppid { return getppid }
sub _linux_getppid { return Linux::Pid::getppid() }
-sub _exit_if_too_big {
- my $r = shift;
-
- return DECLINED
- if ( $CHECK_EVERY_N_REQUESTS
- && ( $REQUEST_COUNT++ % $CHECK_EVERY_N_REQUESTS ) );
+{
+ # Deprecated APIs
- $START_TIME ||= time;
-
- my ( $size, $share ) = check_size();
- my $unshared = $size - $share;
+ sub setmax {
+ my $class = __PACKAGE__;
- if ( ( $MAX_PROCESS_SIZE && $size > $MAX_PROCESS_SIZE )
- || ( $MIN_SHARE_SIZE && $share < $MIN_SHARE_SIZE )
- || ( $MAX_UNSHARED_SIZE && $unshared > $MAX_UNSHARED_SIZE ) ) {
- # wake up! time to die.
- if ( $IS_WIN32 || real_getppid() > 1 ) {
- # this is a child httpd
- my $e = time - $START_TIME;
- my $msg = "httpd process too big, exiting at SIZE=$size KB";
- $msg .= " SHARE=$share KB UNSHARED=$unshared" if ($share);
- $msg .= " REQUESTS=$REQUEST_COUNT LIFETIME=$e seconds";
- _error_log($msg);
+ $class->set_max_process_size(shift);
- if ($IS_WIN32) {
- # child_terminate() is disabled in win32 Apache
- CORE::exit(-2);
- }
- else {
- $r->child_terminate();
- }
- }
- else {
- # this is the main httpd, whose parent is init?
- my $msg = "main process too big, SIZE=$size KB ";
- $msg .= " SHARE=$share KB" if ($share);
- _error_log($msg);
- }
+ $class->add_cleanup_handler();
}
- return OK;
-}
-
-# setmax can be called from within a Registry script to tell the server
-# to exit if the script causes the process to grow too big.
-sub setmax {
- $MAX_PROCESS_SIZE = shift;
-
- _set_post_conn();
-}
-sub setmin {
- $MIN_SHARE_SIZE = shift;
+ sub setmin {
+ my $class = __PACKAGE__;
- _set_post_conn();
-}
+ $class->set_min_shared_size(shift);
-sub setmax_unshared {
- $MAX_UNSHARED_SIZE = shift;
-
- _set_post_conn();
-}
-
-sub _set_post_conn {
- my $r = Apache->request
- or return;
-
- return if $r->pnotes('size_limit_cleanup');
+ $class->add_cleanup_handler();
+ }
- $r->post_connection( \&_exit_if_too_big );
- $r->pnotes( size_limit_cleanup => 1 );
-}
+ sub setmax_unshared {
+ my $class = __PACKAGE__;
-sub handler {
- my $r = shift || Apache->request;
+ $class->set_max_unshared_size(shift);
- return DECLINED unless $r->is_main();
-
- # we want to operate in a cleanup handler
- if ( $r->current_callback eq 'PerlCleanupHandler' ) {
- return _exit_if_too_big($r);
+ $class->add_cleanup_handler();
}
- else {
- $r->post_connection( \&_exit_if_too_big );
- }
-
- return DECLINED;
}
-sub _error_log {
- print STDERR "[", scalar( localtime(time) ),
- "] ($$) Apache::SizeLimit @_\n";
-}
1;
@@ -273,7 +341,9 @@
=head1 SYNOPSIS
<Perl>
- $Apache::SizeLimit::MAX_UNSHARED_SIZE = 120 * 1024; # 120MB
+ Apache::SizeLimit->set_max_process_size(150_000); # Max size in KB
+ Apache::SizeLimit->set_min_shared_size(10_000); # Min share in KB
+ Apache::SizeLimit->set_max_unshared_size(120_000); # Max unshared size in KB
</Perl>
PerlCleanupHandler Apache::SizeLimit
@@ -291,28 +361,49 @@
You can also limit the frequency that these sizes are checked so that
this module only checks every N requests.
-This module is highly platform dependent, please read the CAVEATS
-section.
+This module is highly platform dependent, please read the
+L<PER-PLATFORM BEHAVIOR> section for details. It is possible that this
+module simply does not support your platform.
=head1 API
You can set set the size limits from a Perl module or script loaded by
-Apache:
+Apache by calling the appropriate class method on C<Apache::SizeLimit>:
+
+=over 4
+
+=item * Apache::SizeLimit->set_max_process_size($size)
+
+This sets the maximum size of the process, including both shared and
+unshared memory.
- use Apache::SizeLimit;
+=item * Apache::SizeLimit->set_max_unshared_size($size)
- Apache::SizeLimit::setmax(150_000); # Max size in KB
- Apache::SizeLimit::setmin(10_000); # Min share in KB
- Apache::SizeLimit::setmax_unshared(120_000); # Max unshared size in KB
+This sets the maximum amount of I<unshared> memory the process can
+use.
-Then in your Apache configuration, make Apache::SizeLimit a
-C<PerlCleanupHandler>:
+=item * Apache::SizeLimit->set_min_shared_size($size)
+
+This sets the minimum amount of shared memory the process must have.
+
+=back
+
+The two methods related to shared memory size are effectively a no-op
+if the module cannot determine the shared memory size for your
+platform. See L<PER-PLATFORM BEHAVIOR> for more details.
+
+=head2 Running the handler()
+
+There are several ways to make this module actually run the code to
+kill a process.
+
+The simplest is to make C<Apache::SizeLimit> a C<PerlCleanupHandler>
+in your Apache config:
PerlCleanupHandler Apache::SizeLimit
-Calling any one of C<setmax()>, C<setmin()>, or C<setmax_unshared()>
-will install C<Apache::SizeLimit> as a cleanup handler for the current
-request, if it's not already installed.
+This will ensure that C<< Apache::SizeLimit->handler() >> is called
+run for all requests.
If you want to combine this module with a cleanup handler of your own,
make sure that C<Apache::SizeLimit> is the last handler run:
@@ -322,8 +413,8 @@
Remember, mod_perl will run stacked handlers from right to left, as
they're defined in your configuration.
-You can explicitly call the C<Apache::SizeLimit::handler()> function
-from your own cleanup handler:
+You can also explicitly call the C<< Apache::SizeLimit->handler() >>
+function from your own cleanup handler:
package My::CleanupHandler
@@ -334,64 +425,34 @@
# request
File::Temp::cleanup();
- return Apache::SizeLimit::handler($r);
+ return Apache::SizeLimit->handler($r);
}
-Since checking the process size can take a few system calls on some
-platforms (e.g. linux), you may want to only check the process size
-every N times. To do so, simple set the
-C<$Apache::SizeLimit::CHECK_EVERY_N_REQUESTS> global.
-
- $Apache::SizeLimit::CHECK_EVERY_N_REQUESTS = 2;
-
-Now C<Apache::SizeLimit> will only check the process size on every
-other request.
-
-=head2 Deprecated API
-
-Previous versions of this module documented three globals for defining
-memory size limits:
-
=over 4
-=item * $Apache::SizeLimit::MAX_PROCESS_SIZE
-
-=item * $Apache::SizeLimit::MIN_SHARE_SIZE
+=item * Apache::SizeLimit->add_cleanup_handler($r)
-=item * $Apache::SizeLimit::MAX_UNSHARED_SIZE
+You can call this method inside a request to run C<Apache::SizeLimit>'s
+C<handler()> method for just that request. If this method is called
+repeatedly, it ensures that it only every adds one cleanup handler.
=back
-Direct use of these globals is deprecated, but will continue to work
-for the foreseeable future.
+=head2 Checking Every N Requests
-=head1 ABOUT THIS MODULE
+Since checking the process size can take a few system calls on some
+platforms (e.g. linux), you may not want to check the process size for
+every request.
-This module was written in response to questions on the mod_perl
-mailing list on how to tell the httpd process to exit if it gets too
-big.
+=over 4
-Actually, there are two big reasons your httpd children will grow.
-First, your code could have a bug that causes the process to increase
-in size very quickly. Second, you could just be doing operations that
-require a lot of memory for each request. Since Perl does not give
-memory back to the system after using it, the process size can grow
-quite large.
+=item * Apache::SizeLimit->set_check_interval($interval)
-This module will not really help you with the first problem. For that
-you should probably look into C<Apache::Resource> or some other means
-of setting a limit on the data size of your program. BSD-ish systems
-have C<setrlimit()>, which will kill your memory gobbling processes.
-However, it is a little violent, terminating your process in
-mid-request.
+Calling this causes C<Apache::SizeLimit> to only check the process
+size every C<$interval> requests. If you want this to affect all
+processes, make sure to call this during server startup.
-This module attempts to solve the second situation, where your process
-slowly grows over time. It checks memory usage after every request,
-and if it exceeds a threshold, exits gracefully.
-
-By using this module, you should be able to discontinue using the
-Apache configuration directive B<MaxRequestsPerChild>, although for
-some folks, using both in combination does the job.
+=back
=head1 SHARED MEMORY OPTIONS
@@ -409,7 +470,7 @@
physical RAM, allowing most processes to live longer and reducing the
process churn rate.
-=head1 CAVEATS
+=head1 PER-PLATFORM BEHAVIOR
This module is highly platform dependent, since finding the size of a
process is different for each OS, and some platforms may not be
@@ -423,31 +484,29 @@
=head2 linux
For linux we read the process size out of F</proc/self/statm>. If you
-are worried about performance, see if the CHECK_EVERY_N_REQUESTS
-option is of benefit.
-
-Since linux 2.6 F</proc/self/statm> does not report the amount of
-memory shared by the copy-on-write mechanism as shared memory. Hence
-decisions made on the basis of C<MAX_UNSHARED_SIZE> or
-C<MIN_SHARE_SIZE> are inherently wrong.
-
-To correct this situation, as of the 2.6.14 release of the kernel,
-there is F</proc/self/smaps> entry for each
-process. F</proc/self/smaps> reports various sizes for each memory
-segment of a process and allows us to count the amount of shared
-memory correctly.
+are worried about performance, you can consider using C<<
+Apache::SizeLimit->set_check_interval() >> to reduce how often this
+read happens.
+
+As of linux 2.6, F</proc/self/statm> does not report the amount of
+memory shared by the copy-on-write mechanism as shared memory. This
+means that decisions made based on shared memory as reported by that
+interface are inherently wrong.
+
+However, as of the 2.6.14 release of the kernel, there is
+F</proc/self/smaps> entry for each process. F</proc/self/smaps>
+reports various sizes for each memory segment of a process and allows
+us to count the amount of shared memory correctly.
If C<Apache::SizeLimit> detects a kernel that supports
-F</proc/self/smaps> and if the C<Linux::Smaps> module is installed it
-will use them instead of F</proc/self/statm>. You can prevent
-C<Apache::SizeLimit> from using F</proc/self/smaps> and turn on the
-old behaviour by setting C<$Apache::SizeLimit::USE_SMAPS> to 0.
+F</proc/self/smaps> and the C<Linux::Smaps> module is installed it
+will use that module instead of F</proc/self/statm>.
-NOTE: Reading F</proc/self/smaps> is expensive compared to
+Reading F</proc/self/smaps> is expensive compared to
F</proc/self/statm>. It must look at each page table entry of a
process. Further, on multiprocessor systems the access is
-synchronized with spinlocks. Hence, you may want to set the
-C<CHECK_EVERY_N_REQUESTS> option.
+synchronized with spinlocks. Again, you might consider using C<<
+Apache::SizeLimit->set_check_interval() >>.
=head3 Copy-on-write and Shared Memory
@@ -463,9 +522,9 @@
sub handler {
my $r = shift;
- my ($size, $shared) = $Apache::SizeLimit::check_size();
+ my ($size, $shared) = $Apache::SizeLimit->_check_size();
$x =~ tr/a/b/;
- my ($size2, $shared2) = $Apache::SizeLimit::check_size();
+ my ($size2, $shared2) = $Apache::SizeLimit->_check_size();
$r->content_type('text/plain');
$r->print("1: size=$size shared=$shared\n");
$r->print("2: size=$size2 shared=$shared2\n");
@@ -478,11 +537,11 @@
PerlResponseHandler X
</Location>
-The parent apache allocates memory for the string in C<$x>. The
-C<tr>-command then overwrites all "a" with "b" if the handler is
-called with an argument. This write is done in place, thus, the
-process size doesn't change. Only C<$x> is not shared anymore by means
-of copy-on-write between the parent and the child.
+The parent Apache process allocates memory for the string in
+C<$x>. The C<tr>-command then overwrites all "a" with "b" if the
+handler is called with an argument. This write is done in place, thus,
+the process size doesn't change. Only C<$x> is not shared anymore by
+means of copy-on-write between the parent and the child.
If F</proc/self/smaps> is available curl shows:
@@ -533,6 +592,71 @@
If your platform is not supported, then please send a patch to check
the process size. The more portable/efficient/correct the solution the
better, of course.
+
+=head1 ABOUT THIS MODULE
+
+This module was written in response to questions on the mod_perl
+mailing list on how to tell the httpd process to exit if it gets too
+big.
+
+Actually, there are two big reasons your httpd children will grow.
+First, your code could have a bug that causes the process to increase
+in size very quickly. Second, you could just be doing operations that
+require a lot of memory for each request. Since Perl does not give
+memory back to the system after using it, the process size can grow
+quite large.
+
+This module will not really help you with the first problem. For that
+you should probably look into C<Apache::Resource> or some other means
+of setting a limit on the data size of your program. BSD-ish systems
+have C<setrlimit()>, which will kill your memory gobbling processes.
+However, it is a little violent, terminating your process in
+mid-request.
+
+This module attempts to solve the second situation, where your process
+slowly grows over time. It checks memory usage after every request,
+and if it exceeds a threshold, exits gracefully.
+
+By using this module, you should be able to discontinue using the
+Apache configuration directive B<MaxRequestsPerChild>, although for
+some folks, using both in combination does the job.
+
+=head1 DEPRECATED APIS
+
+Previous versions of this module documented three globals for defining
+memory size limits:
+
+=over 4
+
+=item * $Apache::SizeLimit::MAX_PROCESS_SIZE
+
+=item * $Apache::SizeLimit::MIN_SHARE_SIZE
+
+=item * $Apache::SizeLimit::MAX_UNSHARED_SIZE
+
+=item * $Apache::SizeLimit::CHECK_EVERY_N_REQUESTS
+
+=item * $Apache::SizeLimit::USE_SMAPS
+
+=back
+
+Direct use of these globals is deprecated, but will continue to work
+for the foreseeable future.
+
+It also documented three functions for use from registry scripts:
+
+=over 4
+
+=item * Apache::SizeLimit::setmax()
+
+=item * Apache::SizeLimit::setmin()
+
+=item * Apache::SizeLimit::setmax_unshared()
+
+=back
+
+Besides setting the appropriate limit, these functions I<also> add a
+cleanup handler to the current request.
=head1 AUTHOR
Modified: perl/Apache-SizeLimit/trunk/t/response/TestApache/basic.pm
URL: http://svn.apache.org/viewvc/perl/Apache-SizeLimit/trunk/t/response/TestApache/basic.pm?rev=419300&r1=419299&r2=419300&view=diff
==============================================================================
--- perl/Apache-SizeLimit/trunk/t/response/TestApache/basic.pm (original)
+++ perl/Apache-SizeLimit/trunk/t/response/TestApache/basic.pm Wed Jul 5 11:04:30 2006
@@ -9,22 +9,93 @@
use Apache::SizeLimit;
use Config;
+use constant ONE_MB => 1024;
+use constant TEN_MB => 1024 * 10;
sub handler {
my $r = shift;
- plan $r, tests => 2;
+ plan $r, tests => 12;
- my ( $size, $shared ) = Apache::SizeLimit::check_size();
- cmp_ok( $size, '>', 0, 'proc size is reported > 0' );
+ ok( ! Apache::SizeLimit->_limits_are_exceeded(),
+ 'check that _limits_are_exceeded() returns false without any limits set' );
- SKIP:
{
- skip 'I have no idea what getppid() on Win32 might return', 1
- if 1 $Config{'osname'} eq 'MSWin32';
+ my ( $size, $shared ) = Apache::SizeLimit->_check_size();
+ cmp_ok( $size, '>', 0, 'proc size is reported > 0' );
- cmp_ok( Apache::SizeLimit::real_getppid(), '>', 1,
- 'real_getppid() > 1' );
+ SKIP:
+ {
+ skip 'I have no idea what getppid() on Win32 might return', 1
+ if $Config{'osname'} eq 'MSWin32';
+
+ cmp_ok( Apache::SizeLimit::real_getppid(), '>', 1,
+ 'real_getppid() > 1' );
+ }
+ }
+
+ {
+ # We can assume this will use _at least_ 10MB of memory, based on
+ # assuming a scalar consumes >= 1K.
+ my @big = ('x') x TEN_MB;
+
+ my ( $size, $shared ) = Apache::SizeLimit->_check_size();
+ cmp_ok( $size, '>', TEN_MB, 'proc size is reported > ' . TEN_MB );
+
+ Apache::SizeLimit->set_max_process_size(ONE_MB);
+
+ ok( Apache::SizeLimit->_limits_are_exceeded(),
+ 'check that _limits_are_exceeded() returns true based on max process size' );
+
+ SKIP:
+ {
+ skip 'We cannot get shared memory on this platform.', 3
+ unless $shared > 0;
+
+ cmp_ok( $size, '>', $shared, 'proc size is greater than shared size' );
+
+ Apache::SizeLimit->set_max_process_size(0);
+ Apache::SizeLimit->set_min_shared_size( ONE_MB * 100 );
+
+ ok( Apache::SizeLimit->_limits_are_exceeded(),
+ 'check that _limits_are_exceeded() returns true based on min share size' );
+
+ Apache::SizeLimit->set_min_shared_size(0);
+ Apache::SizeLimit->set_max_unshared_size(1);
+
+ ok( Apache::SizeLimit->_limits_are_exceeded(),
+ 'check that _limits_are_exceeded() returns true based on max unshared size' );
+ }
+ }
+
+ {
+ # Lame test - A way to check that setting this _does_
+ # something would be welcome ;)
+ Apache::SizeLimit->set_check_interval(10);
+ is( $Apache::SizeLimit::CHECK_EVERY_N_REQUESTS, 10,
+ 'set_check_interval set global' );
+ }
+
+ {
+ Apache::SizeLimit->set_max_process_size(0);
+ Apache::SizeLimit->set_min_shared_size(0);
+ Apache::SizeLimit->set_max_unshared_size(0);
+
+ my $handlers = $r->get_handlers('PerlCleanupHandler');
+ is( scalar @$handlers, 0,
+ 'there is no PerlCleanupHandler before add_cleanup_handler()' );
+
+ Apache::SizeLimit->add_cleanup_handler($r);
+
+ $handlers = $r->get_handlers('PerlCleanupHandler');
+ is( scalar @$handlers, 1,
+ 'there is one PerlCleanupHandler after add_cleanup_handler()' );
+
+ Apache::SizeLimit->add_cleanup_handler($r);
+
+ $handlers = $r->get_handlers('PerlCleanupHandler');
+ is( scalar @$handlers, 1,
+ 'there is stil one PerlCleanupHandler after add_cleanup_handler() a second time' );
}
return OK;
Added: perl/Apache-SizeLimit/trunk/t/response/TestApache/deprecated.pm
URL: http://svn.apache.org/viewvc/perl/Apache-SizeLimit/trunk/t/response/TestApache/deprecated.pm?rev=419300&view=auto
==============================================================================
--- perl/Apache-SizeLimit/trunk/t/response/TestApache/deprecated.pm (added)
+++ perl/Apache-SizeLimit/trunk/t/response/TestApache/deprecated.pm Wed Jul 5 11:04:30 2006
@@ -0,0 +1,42 @@
+package TestApache::deprecated;
+
+use strict;
+use warnings;
+
+use Apache::Test qw(-withtestmore);
+
+use Apache::Constants qw(OK);
+use Apache::SizeLimit;
+
+
+sub handler {
+ my $r = shift;
+
+ plan $r, tests => 5;
+
+ my $handlers = $r->get_handlers('PerlCleanupHandler');
+ is( scalar @$handlers, 0,
+ 'there is no PerlCleanupHandler before add_cleanup_handler()' );
+
+ Apache::SizeLimit::setmax( 100_000 );
+ is( $Apache::SizeLimit::MAX_PROCESS_SIZE, 100_000,
+ 'setmax changes $MAX_PROCESS_SIZE' );
+
+ Apache::SizeLimit::setmin( 1 );
+ is( $Apache::SizeLimit::MIN_SHARE_SIZE, 1,
+ 'setmax changes $MIN_SHARE_SIZE' );
+
+ Apache::SizeLimit::setmax_unshared( 1 );
+ is( $Apache::SizeLimit::MIN_SHARE_SIZE, 1,
+ 'setmax_unshared changes $MAX_UNSHARED_SIZE' );
+
+ $handlers = $r->get_handlers('PerlCleanupHandler');
+ is( scalar @$handlers, 1,
+ 'there is one PerlCleanupHandler after calling deprecated functions' );
+
+
+ return OK;
+}
+
+
+1;