NAME
Mojolicious::Plugin::SizeLimit - Terminate workers that grow too large
VERSION
Version 0.005
SYNOPSIS
# Mojolicious
if ($ENV{HYPNOTOAD_APP}) {
$self->plugin('SizeLimit', max_unshared_size => 262_144); # 256M
}
# Mojolicious::Lite
if ($ENV{HYPNOTOAD_APP}) {
plugin 'SizeLimit', max_unshared_size => 262_144;
}
DESCRIPTION
Mojolicious::Plugin::SizeLimit is a Mojolicious plugin that allows to terminate hypnotoad worker processes if they grow too large. The decision to end a process can be based on its overall size, by setting a minimum limit on shared memory, or a maximum on unshared memory.
Actually, there are two big reasons your hypnotoad workers 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 you can't rely that Perl gives 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 "BSD::Resource" or some other means of setting a limit on the data size of your program. BSD-ish systems have "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 N requests, and if it exceeds a threshold, calls "stop_gracefully" in Mojo::IOLoop, what as a result makes the worker stop accepting new connections and terminate as soon as all its pending requests have been processed and served.
By using this module, you should be able to set the configuration directive "accepts" in Mojo::Server::Hypnotoad to 0 (= unlimited). This has the great advantage, that worker processes are not sig-killed by the manager process at end-of-life if they do not finish within "graceful_timeout" in Mojo::Server::Hypnotoad.
OPTIONS
Mojolicious::Plugin::SizeLimit supports the following options.
max_unshared_size
The maximum amount of unshared memory the process can use in KB. Usually this option is all one needs, because it only terminates processes that are truly using too much physical RAM, allowing most processes to live longer and reducing the process churn rate.
On Solaris though unshared size is not available.
max_process_size
The maximum size of the process in KB, including both shared and unshared memory. This must be used on Solaris.
min_shared_size
Sets the minimum amount of shared memory the process must have in KB.
check_interval
Since checking the process size can take a few system calls on some platforms (e.g. linux), you may specify this option to check the process size every N requests.
report_level
This plugin writes a message when a worker is about to terminate after reaching a limit. The message is written using the Mojo::Log method given by report_level
, so any value documented in "level" in Mojo::Log is acceptable, undef
disables the message. The default is "debug"
.
You might want to set report_level
at least to "info"
if you want this message in your production log.
METHODS
Mojolicious::Plugin::SizeLimit inherits all methods from Mojolicious::Plugin and implements the following new ones.
register
$plugin->register(Mojolicious->new);
Register plugin in Mojolicious application.
FUNCTIONS
check_size
($total, $shared) = Mojolicious::Plugin::SizeLimit::check_size();
Returns a list with two memory sizes in KB, first to total process size and second the shared memory size. Not exported. Most usefull for tests.
SEE ALSO
Mojolicious, http://mojolicio.us, Apache::SizeLimit, Plack::Middleware::SizeLimit, Process::SizeLimit::Core.
ACKNOWLEDGEMENTS
Andreas J. Koenig, who told me to write this Mojolicious plugin.
AUTHOR
Bernhard Graf <graf(a)cpan.org>
COPYRIGHT AND LICENSE
Copyright (C) 2015 Bernhard Graf
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
See http://dev.perl.org/licenses/ for more information.