App-karr
view release on metacpan or search on metacpan
lib/App/karr/Foundation/State.pm view on Meta::CPAN
# ABSTRACT: karr-foundation per-repo state â lock file, JSON state, cooldown backoff
package App::karr::Foundation::State;
our $VERSION = '0.401';
use Moo;
use Path::Tiny;
use JSON::MaybeXS qw( encode_json decode_json );
use Try::Tiny;
has foundation => (
is => 'ro',
weak_ref => 1,
required => 1,
);
# ---------------------------------------------------------------------------
# Lock file
# ---------------------------------------------------------------------------
sub _lock_file { path( $_[1]->child('.karr.lock') ) }
sub _lock_held {
my ( $self, $repo ) = @_;
my $lock = $self->_lock_file( $repo );
return 0 unless $lock->exists;
my $pid = $lock->slurp_utf8;
chomp $pid;
return 0 unless $pid =~ /^\d+$/;
# Check if PID is alive
return kill( 0, $pid ) ? 1 : 0;
}
sub _acquire_lock {
my ( $self, $repo ) = @_;
return if $self->foundation->dry_run;
$self->_lock_file( $repo )->spew_utf8( "$$\n" );
}
sub _release_lock {
my ( $self, $repo ) = @_;
return if $self->foundation->dry_run;
my $lock = $self->_lock_file( $repo );
$lock->remove if $lock->exists;
}
# ---------------------------------------------------------------------------
# State file
# ---------------------------------------------------------------------------
sub _state_file { path( $_[1]->child('.karr.state') ) }
sub _state_get {
my ( $self, $repo, $key ) = @_;
my $state_file = $self->_state_file( $repo );
return undef unless $state_file->exists;
my $data = try { decode_json( $state_file->slurp_utf8 ) } catch { {} };
return $data->{$key};
}
sub _state_set {
my ( $self, $repo, %kv ) = @_;
return if $self->foundation->dry_run;
my $state_file = $self->_state_file( $repo );
my $data = {};
if ( $state_file->exists ) {
$data = try { decode_json( $state_file->slurp_utf8 ) } catch { {} };
}
( run in 0.520 second using v1.01-cache-2.11-cpan-5fbc6bb55f2 )