NAME

Mojolicious::Plugin::SizeLimit - Terminate workers that grow too large

VERSION

Version 0.006

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 main 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.

Stefan Corneliu Petrea for kicking my ass.

AUTHOR

Bernhard Graf <graf(a)cpan.org>

COPYRIGHT AND LICENSE

Copyright (C) 2015 - 2020 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.