Catalyst-Plugin-Alarm
view release on metacpan or search on metacpan
sub off {
#Time::HiRes::alarm(0);
CORE::alarm(0);
}
# for those who sleep like I do...
sub snooze { off() }
1;
__END__
=pod
=head1 NAME
Catalyst::Plugin::Alarm - call an action with a timeout value
=head1 SYNOPSIS
package MyApp;
use Catalyst qw( Alarm );
MyApp->config( alarm => {
timeout => 60,
global => 120,
handler => sub { # do something if alarm sounds }
});
sub default : Private {
my ($self,$c) = @_;
unless( $c->timeout('foo') ) {
$c->stash->{error} = "Sorry to keep you waiting. There was a problem.";
return;
}
}
sub foo : Private {
my ($self,$c) = @_;
sleep 61;
}
=head1 DESCRIPTION
Catalyst::Plugin::Alarm implements the timeout_call() function of Sys::SigAction
for both global and local alarms.
You may set a global timeout value that will trigger alarm if the total processing
time of any request exceeds N seconds.
You may call individual actions with timeout values in a manner similar to the
standard forward() method.
B<NOTE:> Using alarms in a web application is not without peril, as any number of factors
could contribute to legitimately slowing down your application. The Alarm plugin should
be used only when you need to catch things that a browser's timeout feature won't catch.
=head1 CONFIGURATION
You may set default values in your config() hash, using the C<alarm> key.
Timeout values should be indicated in seconds and
B<must> be integers. The added float granularity of Time::HiRes is not available
for the alarm values due to the way sleep() and alarm() interact (i.e., they
do not play together predictably).
=over
=item timeout I<N>
The default time to wait in the timeout() method.
=item global I<N>
The default time to wait for the entire request to finish. Default time is
three minutes (180 seconds). If your app will legitimately take longer than
that to finish a request, you should set it higher.
To disable global timeouts entirely, set I<N> to C<0>.
=item handler I<coderef>
Set a handler for timeouts. Will be used in both global timeouts and the
timeout() method. The default is to throw() a Catalyst::Exception with a
(hopefully) helpful message about the alarm.
I<coderef> can expect to receive the following arguments:
=over
=item $controller
The current controller object.
=item \@return or 1
If the alarm is the global alarm, the second value in @_ will be a 1. If the alarm
is a local alarm (from timeout() or forward()) then the second value will be a reference
to the array returned from your forwarded action.
The on() flag is significant in this case because if false, then the @return value will
be returned from the timeout() method. Otherwise, if on() is true, timeout() will
return undef.
Thus you can make alarms non-fatal by defining a handler that just notifies you
when an alarm went off and resetting the on() flag.
Example:
__PACKAGE__->config( alarm => {
handler => sub {
if (ref $_[1]) {
$_[0]->log->error(" .... local alarm went off!!");
$_[1]->[0] = 'some return value';
$_[0]->alarm->on(0); # turn 'off' the alarm flag
}
else {
$_[0]->log->error(" .... global alarm went off");
$_[0]->alarm->on(1);
}
}
( run in 0.890 second using v1.01-cache-2.11-cpan-39bf76dae61 )