File Coverage

blib/lib/Beam/Runnable/Single.pm
Criterion Covered Total %
statement 12 12 100.0
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 16 16 100.0


line stmt bran cond sub pod time code
1             package Beam::Runnable::Single;
2             our $VERSION = '0.015';
3             # ABSTRACT: Only allow one instance of this command at a time
4              
5             #pod =head1 SYNOPSIS
6             #pod
7             #pod ### In a Runnable module
8             #pod package My::Runnable::Script;
9             #pod use Moo;
10             #pod with 'Beam::Runnable', 'Beam::Runnable::Single';
11             #pod has '+pid_file' => ( default => '/var/run/runnable-script.pid' );
12             #pod sub run { }
13             #pod
14             #pod ### In a container config file
15             #pod runnable:
16             #pod $class: My::Runnable::Script
17             #pod $with:
18             #pod - 'Beam::Runnable::Single'
19             #pod pid_file: /var/run/runnable-script.pid
20             #pod
21             #pod =head1 DESCRIPTION
22             #pod
23             #pod This role checks to ensure that only one instance of the command is
24             #pod running at a time. If another instance tries to run, it dies with an
25             #pod error instead.
26             #pod
27             #pod Users should have access to read/write the path pointed to by
28             #pod L, and to read/write the directory containing the PID file.
29             #pod
30             #pod If the command exits prematurely, the PID file will not be cleaned up.
31             #pod If this is undesirable, make sure to trap exceptions in your C
32             #pod method and return the exit code you want.
33             #pod
34             #pod =head1 SEE ALSO
35             #pod
36             #pod L
37             #pod
38             #pod =cut
39              
40 1     1   593 use strict;
  1         4  
  1         34  
41 1     1   15 use warnings;
  1         2  
  1         24  
42 1     1   9 use Moo::Role;
  1         1  
  1         10  
43 1     1   843 use Types::Path::Tiny qw( Path );
  1         21527  
  1         8  
44              
45             #pod =attr pid_file
46             #pod
47             #pod The path to a file containing the PID of the currently-running script.
48             #pod
49             #pod =cut
50              
51             has pid_file => (
52             is => 'ro',
53             isa => Path,
54             required => 1,
55             coerce => 1,
56             );
57              
58             #pod =method run
59             #pod
60             #pod This role wraps the C method of your runnable class to check that
61             #pod there is no running instance of this task (the PID file does not exist).
62             #pod
63             #pod =cut
64              
65             before run => sub {
66             my ( $self, @args ) = @_;
67             if ( $self->pid_file->exists ) {
68             my $pid = $self->pid_file->slurp;
69             die "Process already running (PID: $pid)\n";
70             }
71             $self->pid_file->spew( $$ );
72             };
73              
74             after run => sub {
75             my ( $self ) = @_;
76             unlink $self->pid_file;
77             };
78              
79             1;
80              
81             __END__