Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the Log-Dispatch CPAN distribution.

Report information
The Basics
Id: 54421
Status: resolved
Priority: 0/
Queue: Log-Dispatch

People
Owner: Nobody in particular
Requestors: perl [...] events.soundwave.net
Cc:
AdminCc:

Bug Information
Severity: Wishlist
Broken in: 2.26
Fixed in: (no value)



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' );