File Coverage

blib/lib/Launcher/Cascade/Simple.pm
Criterion Covered Total %
statement 29 29 100.0
branch 6 6 100.0
condition 2 3 66.6
subroutine 9 9 100.0
pod 6 6 100.0
total 52 53 98.1


line stmt bran cond sub pod time code
1             package Launcher::Cascade::Simple;
2              
3             =head1 NAME
4              
5             Launcher::Cascade::Simple - a simple implementation for a Launcher, based on
6             callbacks.
7              
8             =head1 SYNOPSIS
9              
10             use Launcher::Cascade::Simple;
11              
12             sub test_method {
13             my $self = shift;
14             if ( ... ) { return SUCCESS }
15             elsif ( ... ) { return FAILURE }
16             else { return UNDEFINED }
17             }
18             sub launch_method {
19             my $self = shift;
20             ...
21             }
22             my $launcher = new Launcher::Cascade::Simple
23             -name => 'simple',
24             -test_hook => \&test_method,
25             -launch_hook => \&launch_method,
26             ;
27              
28             =head1 DESCRIPTION
29              
30             A Launcher::Cascade class only has to provide methods to launch() a process,
31             and to test() whether it succeeded. One way is to create a subclass of
32             C and to overload the methods there.
33              
34             For simple cases, however, it might be easier to instantiate a
35             C and provide it with two callbacks, one for
36             launching and one for testing.
37              
38             =cut
39              
40 7     7   311304 use strict;
  7         15  
  7         280  
41 7     7   39 use warnings;
  7         16  
  7         220  
42              
43 7     7   40 use base qw( Launcher::Cascade::Base Exporter );
  7         16  
  7         4467  
44              
45             =head2 Exports
46              
47             =over 4
48              
49             =item B
50              
51             =item B
52              
53             =item B
54              
55             =back
56              
57             Launcher::Cascade::Simple exports the constant methods C, C
58             and C as defined in Launcher::Cascade::Base. These can be used as
59             constants in the fonction given to test_hook().
60              
61             =cut
62              
63             our @EXPORT = qw( SUCCESS FAILURE UNDEFINED );
64              
65 1     1 1 21 sub SUCCESS { __PACKAGE__->SUPER::SUCCESS () }
66 1     1 1 19 sub FAILURE { __PACKAGE__->SUPER::FAILURE () }
67 9     9 1 386 sub UNDEFINED { __PACKAGE__->SUPER::UNDEFINED () }
68              
69             =head2 Attributes
70              
71             Attributes are accessed through accessor methods. These methods, when called
72             without an argument, will return the attribute's value. With an argument, they
73             will set the attribute's value to that argument, and return the former value.
74              
75             =over 4
76              
77             =item B
78              
79             =item B
80              
81             Callbacks that will be invoked when calling the launch() and test() methods,
82             respectively. The callbacks will receive whatever arguments were given to
83             launch() or test(), including the reference to the object itself (the callbacks
84             can thus be considered as methods).
85              
86             In addition, test_hook() can be given a arrayref of callbacks, in order to
87             implement several tests that depend on each other, as in:
88              
89             $launcher->test_hook([sub { ... }, sub { ... }, sub { ... }]);
90              
91             In that case, test() will invoke each callback in turn. If it fails, test()
92             will immediately return failure. If it succeeds, test() will proceed with the
93             next callback. If it is undefined, test() will retry the same callback at its
94             next attempt, if max_retries() is not null.
95              
96             =back
97              
98             =cut
99              
100             Launcher::Cascade::make_accessors qw( launch_hook test_hook _current_test_stack );
101              
102             =head2 Methods
103              
104             =over 4
105              
106             =item B
107              
108             This method overrides that from C and invokes the
109             callback given in the launch_hook() attribute.
110              
111             =cut
112              
113             sub launch {
114              
115 17     17 1 85 $_[0]->launch_hook()->(@_);
116             }
117              
118             =item B
119              
120             This method overrides that from C and either,
121              
122             =over 5
123              
124             =item *
125              
126             invokes the one callback given in the test_hook() attribute,
127              
128             =item *
129              
130             or invokes, one after another, the callbacks given in the test_hook()
131             attribute, until one of them fails or all of them succeed. If the result of the
132             test is undefined, the same callback will be invoked at next attempt, provided
133             that max_retries() is not null.
134              
135             =back
136              
137             =cut
138              
139             sub test {
140              
141 39     39 1 62 my $self = shift;
142 39 100       178 if ( UNIVERSAL::isa($self->test_hook(), 'ARRAY') ) {
143 18 100       22 my @test = @{$self->_current_test_stack() || $self->test_hook()};
  18         45  
144 18         22 my $result;
145 18         39 while ( @test ) {
146 22         74 $result = $test[0]->($self, @_);
147 22 100 66     144 if ( defined($result) && $result > 0 ) {
148 5         16 shift @test;
149             }
150             else {
151 17         24 last;
152             }
153             }
154 18         52 $self->_current_test_stack(\@test);
155 18         59 return $result;
156             }
157             else {
158 21         79 $self->test_hook()->($self, @_);
159             }
160             }
161              
162             =item B
163              
164             Reset the object's status so that it can be run again.
165              
166             =cut
167              
168             sub reset {
169              
170 8     8 1 24 my $self = shift;
171 8         61 $self->SUPER::reset(@_);
172 8         28 $self->_current_test_stack(undef);
173             }
174              
175             =back
176              
177             =head1 SEE ALSO
178              
179             L
180              
181             =head1 AUTHOR
182              
183             Cédric Bouvier C<< >>
184              
185             =head1 COPYRIGHT & LICENSE
186              
187             Copyright (C) 2006 Cédric Bouvier, All Rights Reserved.
188              
189             This program is free software; you can redistribute it and/or modify it under
190             the same terms as Perl itself.
191              
192             =cut
193              
194             1; # end of Launcher::Cascade::Simple