Subject: | patch: Log::Dispatch::File::Locked allows timeout on flock |
This patch allows a 'timeout' option to be specified for
Log::Dispatch::File::Locked. A value of undef means no timeout (wait
for ever) while a value of 0 means LOCK_NB. Other values will cause the
flock to timeout after the specified number of seconds.
Subject: | flock-timeout.patch |
diff -ur Log-Dispatch-2.26.orig/lib/Log/Dispatch/File/Locked.pm Log-Dispatch-2.26/lib/Log/Dispatch/File/Locked.pm
--- Log-Dispatch-2.26.orig/lib/Log/Dispatch/File/Locked.pm 2009-09-22 14:52:28.000000000 -0700
+++ Log-Dispatch-2.26/lib/Log/Dispatch/File/Locked.pm 2010-02-08 11:18:53.000000000 -0800
@@ -14,12 +14,33 @@
{
my $self = shift;
- $self->SUPER::_open_file();
+ my %p = @_;
+ my $timeout = $p{timeout};
+
+ $self->SUPER::_open_file(@_);
my $fh = $self->{fh};
- flock($fh, LOCK_EX)
- or die "Cannot lock '$self->{filename}' for writing: $!";
+ eval
+ {
+ local $SIG{ALRM} = sub { die 'Timed out waiting for lock' };
+
+ my $lock_mode = LOCK_EX;
+ $lock_mode |= LOCK_NB if defined $timeout and !$timeout;
+
+ alarm $timeout if defined $timeout and $timeout;
+
+ flock($fh, $lock_mode)
+ or die "Cannot lock '$self->{filename}' for writing: $!";
+
+ alarm 0;
+ };
+ alarm 0;
+
+ if ($@)
+ {
+ die "Cannot lock '$self->{filename}' for writing: $@";
+ }
# just in case there was an append while we waited for the lock
seek($fh, 0, 2)
Only in Log-Dispatch-2.26/lib/Log/Dispatch/File: .Locked.pm.swp
diff -ur Log-Dispatch-2.26.orig/lib/Log/Dispatch/File.pm Log-Dispatch-2.26/lib/Log/Dispatch/File.pm
--- Log-Dispatch-2.26.orig/lib/Log/Dispatch/File.pm 2009-09-22 14:52:28.000000000 -0700
+++ Log-Dispatch-2.26/lib/Log/Dispatch/File.pm 2010-02-08 11:12:36.000000000 -0800
@@ -74,7 +74,7 @@
$self->{autoflush} = $p{autoflush};
- $self->_open_file() unless $p{close_after_write};
+ $self->_open_file(@_) unless $p{close_after_write};
}
diff -ur Log-Dispatch-2.26.orig/t/01-basic.t Log-Dispatch-2.26/t/01-basic.t
--- Log-Dispatch-2.26.orig/t/01-basic.t 2009-09-22 14:52:28.000000000 -0700
+++ Log-Dispatch-2.26/t/01-basic.t 2010-02-08 11:21:00.000000000 -0800
@@ -1,8 +1,9 @@
use strict;
use warnings;
-use Test::More tests => 165;
+use Test::More tests => 167;
+use Fcntl qw(:DEFAULT :flock);
use File::Spec;
use File::Temp qw( tempdir );
use Log::Dispatch;
@@ -25,6 +26,7 @@
}
use Log::Dispatch::File;
+use Log::Dispatch::File::Locked;
use Log::Dispatch::Handle;
use Log::Dispatch::Null;
use Log::Dispatch::Screen;
@@ -79,6 +81,49 @@
"Second line in log file set to level 'debug' is 'emerg level 2'" );
}
+# Log::Dispatch::File::Locked
+{
+ my $dispatch = Log::Dispatch->new;
+
+ my $locked_log = File::Spec->catfile( $tempdir, 'locked.log' );
+
+ open my $fh, '>', $locked_log
+ or die "Can't write $locked_log: $!";
+
+ flock( $fh, LOCK_EX|LOCK_NB )
+ or die "Can't get lock on $locked_log: $!";
+
+ eval
+ {
+ $dispatch->add(
+ Log::Dispatch::File::Locked->new( name => 'locked',
+ min_level => 'info',
+ filename => $locked_log,
+ permissions => 0777,
+ close_after_write => 0,
+ timeout => 1 ) );
+ };
+
+ like( $@, qr/^Cannot lock.*Timed out waiting for lock/,
+ 'flock did not time out when timneout option was specified' );
+
+ eval
+ {
+ $dispatch->add(
+ Log::Dispatch::File::Locked->new( name => 'locked',
+ min_level => 'info',
+ filename => $locked_log,
+ permissions => 0777,
+ close_after_write => 0,
+ timeout => 0 ) );
+ };
+
+ like( $@, qr/^Cannot lock.*Resource temporarily unavailable/,
+ 'flock did not fail when timeout was set to 0' );
+
+ close $fh;
+}
+
# max_level test
{
my $max_log = File::Spec->catfile( $tempdir, 'max.log' );