File Coverage

blib/lib/IPC/Concurrency/DBI/Application/Instance.pm
Criterion Covered Total %
statement 32 32 100.0
branch 9 12 75.0
condition n/a
subroutine 8 8 100.0
pod 3 3 100.0
total 52 55 94.5


line stmt bran cond sub pod time code
1             package IPC::Concurrency::DBI::Application::Instance;
2              
3 21     21   26550 use warnings;
  21         42  
  21         840  
4 21     21   116 use strict;
  21         40  
  21         617  
5              
6 21     21   1250 use Data::Dumper;
  21         13774  
  21         941  
7 21     21   112 use Carp;
  21         35  
  21         8903  
8              
9              
10             =head1 NAME
11              
12             IPC::Concurrency::DBI::Application::Instance - Application instance that represents consumption of the limited resource.
13              
14              
15             =head1 VERSION
16              
17             Version 1.1.3
18              
19             =cut
20              
21             our $VERSION = '1.1.3';
22              
23              
24             =head1 SYNOPSIS
25              
26             This module represents one instance of an application managed by
27             IPC::Concurrency::DBI.
28              
29             See the documentation of IPC::Concurrency::DBI for more information.
30              
31             my $instance = $concurrent_program->start_instance();
32             unless ( defined( $instance ) )
33             {
34             print "Too many instances of $0 are already running.\n";
35             exit;
36             }
37              
38             # [...] Do some work.
39              
40             # Now that the application is about to exit, flag the instance as completed.
41             # (note: this is implicit when $instance is destroyed).
42             $instance->finish();
43              
44              
45             =head1 METHODS
46              
47             =head2 new()
48              
49             Create a new IPC::Concurrency::DBI::Application::Instance object.
50              
51             This function should not be called directly and its API could change, instead
52             use IPC::Concurrency::DBI::Application::start_instance().
53              
54             # Retrieve the application by name.
55             my $instance = IPC::Concurrency::DBI::Application::Instance->new(
56             application => $application,
57             );
58              
59             'application': mandatory, an IPC::Concurrency::DBI::Application object.
60              
61             =cut
62              
63             sub new
64             {
65 8     8 1 6328 my ( $class, %args ) = @_;
66 8         27 my $application = delete( $args{'application'} );
67              
68             # Check parameters.
69 8 100       51 croak "Argument 'application' is required to create a new IPC::Concurrency::DBI::Application::Instance object"
70             unless defined( $application );
71 7 100       43 croak "Argument 'application' is not an IPC::Concurrency::DBI::Application"
72             if !Data::Validate::Type::is_instance( $application, class => 'IPC::Concurrency::DBI::Application' );
73              
74             # Create the object.
75 6         261 my $self = bless(
76             {
77             application => $application,
78             finished => 0,
79             },
80             $class,
81             );
82              
83 6         34 return $self;
84             }
85              
86              
87             =head2 finish()
88              
89             Declare that the current instance has finished running and free the slot for
90             a new instance.
91              
92             =cut
93              
94             sub finish
95             {
96 6     6 1 49 my ( $self ) = @_;
97 6         23 my $application = $self->get_application();
98 6         34 my $database_handle = $application->get_database_handle();
99              
100             # If the object has already been destroyed, we have a problem.
101 6 50       27 croak 'The instance has already been marked as finished'
102             if $self->{'finished'};
103              
104             # Decrement the count of running instances, provided that it's > 0.
105             # We should never encounter the case that would make it go negative, but
106             # being careful never hurts.
107 6         45 my $rows_affected = $database_handle->do(
108             q|
109             UPDATE ipc_concurrency_applications
110             SET current_instances = current_instances - 1, modified = ?
111             WHERE ipc_concurrency_application_id = ?
112             AND current_instances > 0
113             |,
114             {},
115             time(),
116             $application->get_id(),
117             );
118 6 50       82833 croak 'Cannot execute SQL: ' . $database_handle->errstr()
119             if defined( $database_handle->errstr() );
120              
121 6         27 $self->{'finished'} = 1;
122              
123 6         26 return 1;
124             }
125              
126              
127             =head1 INTERNAL METHODS
128              
129             =head2 get_application()
130              
131             Returns the parent IPC::Concurrency::DBI::Application object.
132              
133             my $application = $instance->get_application();
134              
135             =cut
136              
137             sub get_application
138             {
139 7     7 1 44 my ( $self ) = @_;
140              
141 7         30 return $self->{'application'};
142             }
143              
144              
145             =head2 DESTROY()
146              
147             Automatically clear the slot used by the current instance when the object
148             is destroyed, if finish() has not been called already.
149              
150             =cut
151              
152             sub DESTROY
153             {
154 6     6   3493 my( $self ) = @_;
155              
156 6 100       59 $self->finish()
157             unless $self->{'finished'};
158              
159 6 50       96 $self->SUPER::DESTROY()
160             if $self->can( 'SUPER::DESTROY' );
161              
162 6         806 return;
163             }
164              
165              
166             =head1 BUGS
167              
168             Please report any bugs or feature requests through the web interface at
169             L.
170             I will be notified, and then you'll automatically be notified of progress on
171             your bug as I make changes.
172              
173              
174             =head1 SUPPORT
175              
176             You can find documentation for this module with the perldoc command.
177              
178             perldoc IPC::Concurrency::DBI
179              
180              
181             You can also look for information at:
182              
183             =over 4
184              
185             =item * GitHub's request tracker
186              
187             L
188              
189             =item * AnnoCPAN: Annotated CPAN documentation
190              
191             L
192              
193             =item * CPAN Ratings
194              
195             L
196              
197             =item * MetaCPAN
198              
199             L
200              
201             =back
202              
203              
204             =head1 AUTHOR
205              
206             L,
207             C<< >>.
208              
209              
210             =head1 COPYRIGHT & LICENSE
211              
212             Copyright 2011-2014 Guillaume Aubert.
213              
214             This program is free software: you can redistribute it and/or modify it under
215             the terms of the GNU General Public License version 3 as published by the Free
216             Software Foundation.
217              
218             This program is distributed in the hope that it will be useful, but WITHOUT ANY
219             WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
220             PARTICULAR PURPOSE. See the GNU General Public License for more details.
221              
222             You should have received a copy of the GNU General Public License along with
223             this program. If not, see http://www.gnu.org/licenses/
224              
225             =cut
226              
227             1;