Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
  • 2 commits
  • 4 files changed
  • 0 commit comments
  • 1 contributor
Commits on May 05, 2012
Jeffrey Ryan Thalhammer Fixed incorrect usage of skip_all.
Thanks CPAN testers!
b9668a2
Jeffrey Ryan Thalhammer Switch to using File::NFSLock.
LockFile::Simple uses some deprecated syntax, which
causes lots of warnings with newer perls.

File:NFSLock also has shared and exclusive locks,
which will come in handy.
09d094d
View
4 lib/Pinto.pm
@@ -60,7 +60,7 @@ sub run {
my $action_class = $self->action_base_class . "::$action_name";
Class::Load::load_class($action_class);
- $self->repos->lock;
+ $self->repos->lock_exclusive;
my $guard = $self->repos->db->schema->txn_scope_guard;
@args{qw(logger repos)} = ($self->logger, $self->repos);
@@ -101,7 +101,7 @@ sub add_logger {
#------------------------------------------------------------------------------
-__PACKAGE__->meta->make_immutable();
+__PACKAGE__->meta->make_immutable;
#-----------------------------------------------------------------------------
View
78 lib/Pinto/Locker.pm
@@ -1,11 +1,11 @@
-package Pinto::Locker;
+# ABSTRACT: Manage locks to synchronize concurrent operations
-# ABSTRACT: Synchronize concurrent Pinto actions
+package Pinto::Locker;
use Moose;
use Path::Class;
-use LockFile::Simple;
+use File::NFSLock;
use Pinto::Types qw(File);
use Pinto::Exception qw(throw);
@@ -17,48 +17,29 @@ use namespace::autoclean;
# VERSION
#-----------------------------------------------------------------------------
-# Moose attributes
+
+has timeout => (
+ is => 'ro',
+ isa => 'Int',
+ default => 50
+);
+
has _lock => (
is => 'rw',
- isa => 'LockFile::Lock',
+ isa => 'File::NFSLock',
predicate => 'is_locked',
init_arg => undef,
);
-has _lockmgr => (
- is => 'ro',
- isa => 'LockFile::Simple',
- init_arg => undef,
- lazy_build => 1,
-);
-
#-----------------------------------------------------------------------------
-# Moose roles
with qw( Pinto::Role::Configurable
Pinto::Role::Loggable );
#-----------------------------------------------------------------------------
-# Builders
-
-sub _build__lockmgr {
- my ($self) = @_;
-
- my $wfunc = sub { $self->debug(@_) };
- my $efunc = sub { throw(@_) };
- return LockFile::Simple->make( -autoclean => 1,
- -efunc => $efunc,
- -wfunc => $wfunc,
- -stale => 1,
- -nfs => 1 );
-}
-
-#-----------------------------------------------------------------------------
-# Methods
-
-=method lock()
+=method lock
Attempts to get a lock on a Pinto repository. If the repository is already
locked, we will attempt to contact the current lock holder and make sure they
@@ -67,20 +48,35 @@ we patiently wait until we timeout, which is about 60 seconds.
=cut
-sub lock { ## no critic (Homonym)
+sub lock_exclusive {
my ($self) = @_;
- my $root_dir = $self->config->root_dir;
+ my $root_dir = $self->root_dir;
+ throw "$root_dir is already locked" if $self->is_locked;
+
+ my $lock_file = $root_dir->file('.lock')->stringify;
+ my $lock = File::NFSLock->new($lock_file, 'EX', $self->timeout)
+ or throw 'Unable to lock the repository -- please try later';
+
+ $self->debug("Process $$ got exclusive lock on $root_dir");
+ $self->_lock($lock);
+
+ return $self;
+}
+
+#-----------------------------------------------------------------------------
+
+sub lock_shared {
+ my ($self) = @_;
- # If by chance, the directory we are trying to lock does not exist,
- # then LockFile::Simple will wait (a while) until it does. To
- # avoid this extra delay, just make sure the directory exists now.
- throw "Repository $root_dir does not exist" if not -e $root_dir;
+ my $root_dir = $self->root_dir;
+ throw "$root_dir is already locked" if $self->is_locked;
- my $lock = $self->_lockmgr->lock( $root_dir->file('')->stringify )
+ my $lock_file = $root_dir->file('.lock')->stringify;
+ my $lock = File::NFSLock->new($lock_file, 'SH', $self->timeout)
or throw 'Unable to lock the repository -- please try later';
- $self->debug("Process $$ got the lock on $root_dir");
+ $self->debug("Process $$ got shared lock on $root_dir");
$self->_lock($lock);
return $self;
@@ -88,7 +84,7 @@ sub lock { ## no critic (Homonym)
#-----------------------------------------------------------------------------
-=method unlock()
+=method unlock
Releases the lock on the Pinto repository so that other processes can
get to work.
@@ -100,7 +96,7 @@ sub unlock {
return $self if not $self->is_locked;
- $self->_lock->release or throw 'Unable to unlock repository';
+ $self->_lock->unlock or throw 'Unable to unlock repository';
my $root_dir = $self->config->root_dir;
$self->debug("Process $$ released the lock on $root_dir");
View
6 lib/Pinto/Repository.pm
@@ -76,7 +76,9 @@ has cache => (
logger => $_[0]->logger ) },
);
-=method lock
+=method lock_shared
+
+=method lock_exclusive
=method unlock
@@ -86,7 +88,7 @@ has locker => (
is => 'ro',
isa => 'Pinto::Locker',
lazy => 1,
- handles => [ qw(lock unlock) ],
+ handles => [ qw(lock_shared lock_exclusive unlock) ],
default => sub { Pinto::Locker->new( config => $_[0]->config,
logger => $_[0]->logger ) },
);
View
2  t/35-install.t
@@ -15,7 +15,7 @@ use Pinto::Tester::Util qw(make_dist_archive);
#------------------------------------------------------------------------------
-skip_all('cpanm required for install tests') unless which('cpanm');
+plan skip_all => 'cpanm required for install tests' unless which('cpanm');
#------------------------------------------------------------------------------

No commit comments for this range

Something went wrong with that request. Please try again.