File Coverage

blib/lib/IO/Iron/IronWorker/Task.pm
Criterion Covered Total %
statement 26 148 17.5
branch 0 44 0.0
condition n/a
subroutine 11 41 26.8
pod 27 27 100.0
total 64 260 24.6


line stmt bran cond sub pod time code
1             package IO::Iron::IronWorker::Task;
2              
3             ## no critic (Documentation::RequirePodAtEnd)
4             ## no critic (Documentation::RequirePodSections)
5             ## no critic (ControlStructures::ProhibitPostfixControls)
6             ## no critic (Subroutines::RequireArgUnpacking)
7              
8 4     4   71 use 5.010_000;
  4         24  
9 4     4   22 use strict;
  4         8  
  4         79  
10 4     4   20 use warnings;
  4         8  
  4         107  
11              
12             # Global creator
13       4     BEGIN {
14             }
15              
16             # Global destructor
17       4     END {
18             }
19              
20             # ABSTRACT: IronWorker (Online Worker Platform) Client (Task).
21              
22             our $VERSION = '0.14'; # VERSION: generated by DZP::OurPkgVersion
23              
24 4     4   25 use Log::Any qw($log);
  4         24  
  4         23  
25 4     4   830 use Hash::Util 0.06 qw{lock_keys unlock_keys};
  4         75  
  4         23  
26 4     4   280 use Carp::Assert::More;
  4         9  
  4         807  
27 4     4   29 use English '-no_match_vars';
  4         16  
  4         22  
28 4     4   1464 use Params::Validate qw(:all);
  4         8  
  4         651  
29              
30 4     4   67 use IO::Iron::IronWorker::Api ();
  4         31  
  4         8189  
31              
32             # CONSTANTS for this module
33              
34             # DEFAULTS
35             #my $DEFAULT_DELAY = 0;
36             #my $DEFAULT_TIMEOUT = 3600;
37             #my $DEFAULT_PRIORITY = 0;
38              
39             sub new { ## no critic (Subroutines::ProhibitExcessComplexity)
40 0     0 1   my ( $class, $params ) = @_;
41 0           $log->tracef( 'Entering new(%s, %s)', $class, $params );
42 0           my $self;
43 0           my @self_keys = ( ## no critic (CodeLayout::ProhibitQuotedWordLists)
44             'ironworker_client', # Reference to IronWorker client
45             'connection', # Reference to REST client
46             'last_http_status_code', # After successfull network operation, the return value is here.
47             # Can be given when queueing a new task:
48             'code_name', # The name of the code package to execute for this task (mandatory).
49             'payload', # A string of data to be passed to the worker (usually JSON), can be empty (mandatory).
50             'priority', # The priority queue to run the task in. Valid values are 0, 1, and 2. 0 is the default.
51             'timeout', # The maximum runtime of your task in seconds.
52             'delay', # The number of seconds to delay before actually queuing the task. Default is 0.
53             'name', # Name of task or scheduled task.
54             # These are for scheduled task:
55             'run_every', # The amount of time, in seconds, between runs
56             'end_at', # The time tasks will stop being queued. Should be a time or datetime.
57             'run_times', # The number of times a task will run.
58             'start_at', # The time the scheduled task should first be run.
59             # Returned when queried a queued task:
60             'id', # Task or Scheduled task id.
61             'project_id', # Iron.io project ID.
62             'code_id', # The code package id.
63             'status', # Task execution status.
64             'code_history_id', # Code package revision id?
65             'code_rev', # Code package revision number.
66             'start_time', # Execution started?
67             'end_time', # Execution finished?
68             'duration', # Execution duration?
69             'updated_at', # Timestamp (ISO) of last update.
70             'created_at', # Timestamp (ISO) of creation. E.g. "2012-11-10T18:31:08.064Z"
71             );
72 0           lock_keys( %{$self}, @self_keys );
  0            
73 0 0         $self->{'ironworker_client'} = $params->{'ironworker_client'} if defined $params->{'ironworker_client'};
74 0 0         $self->{'connection'} = $params->{'connection'} if defined $params->{'connection'};
75 0           assert_isa( $self->{'connection'}, 'IO::Iron::Connection', 'self->{\'connection\'} is IO::Iron::Connection.' );
76             assert_isa(
77 0           $self->{'ironworker_client'},
78             'IO::Iron::IronWorker::Client',
79             'self->{\'ironworker_client\'} is IO::Iron::IronWorker::Client.'
80             );
81              
82 0           $self->{'code_name'} = $params->{'code_name'};
83 0           $self->{'payload'} = $params->{'payload'};
84 0 0         $self->{'priority'} = $params->{'priority'} if defined $params->{'priority'};
85 0 0         $self->{'timeout'} = $params->{'timeout'} if defined $params->{'timeout'};
86 0 0         $self->{'delay'} = $params->{'delay'} if defined $params->{'delay'};
87              
88 0 0         $self->{'run_every'} = $params->{'run_every'} if defined $params->{'run_every'};
89 0 0         $self->{'end_at'} = $params->{'end_at'} if defined $params->{'end_at'};
90 0 0         $self->{'run_times'} = $params->{'run_times'} if defined $params->{'run_times'};
91 0 0         $self->{'start_at'} = $params->{'start_at'} if defined $params->{'start_at'};
92              
93 0 0         $self->{'id'} = $params->{'id'} if defined $params->{'id'};
94 0 0         $self->{'project_id'} = $params->{'project_id'} if defined $params->{'project_id'};
95 0 0         $self->{'code_id'} = $params->{'code_id'} if defined $params->{'code_id'};
96 0 0         $self->{'status'} = $params->{'status'} if defined $params->{'status'};
97 0 0         $self->{'code_history_id'} = $params->{'code_history_id'} if defined $params->{'code_history_id'};
98 0 0         $self->{'code_rev'} = $params->{'code_rev'} if defined $params->{'code_rev'};
99 0 0         $self->{'start_time'} = $params->{'start_time'} if defined $params->{'start_time'};
100 0 0         $self->{'end_time'} = $params->{'end_time'} if defined $params->{'end_time'};
101 0 0         $self->{'duration'} = $params->{'duration'} if defined $params->{'duration'};
102 0 0         $self->{'updated_at'} = $params->{'updated_at'} if defined $params->{'updated_at'};
103 0 0         $self->{'created_at'} = $params->{'created_at'} if defined $params->{'created_at'};
104 0 0         $self->{'name'} = $params->{'name'} if defined $params->{'name'};
105              
106             # All of the above can be undefined, except the codename and payload.
107 0           assert_nonblank( $self->{'code_name'}, 'code_name is defined and is not blank.' );
108 0           assert_defined( $self->{'payload'}, 'payload is defined, can be blank.' );
109              
110             # If priority, timeout or delay are undefined, the IronWorker defaults (at the server) will be used.
111              
112 0           unlock_keys( %{$self} );
  0            
113 0           my $blessed_ref = bless $self, $class;
114 0           lock_keys( %{$self}, @self_keys );
  0            
115              
116 0           $log->tracef( 'Exiting new: %s', $blessed_ref );
117 0           return $blessed_ref;
118             }
119              
120 0     0 1   sub code_name { return $_[0]->_access_internal( 'code_name', $_[1] ); }
121 0     0 1   sub payload { return $_[0]->_access_internal( 'payload', $_[1] ); }
122 0     0 1   sub priority { return $_[0]->_access_internal( 'priority', $_[1] ); }
123 0     0 1   sub timeout { return $_[0]->_access_internal( 'timeout', $_[1] ); }
124 0     0 1   sub delay { return $_[0]->_access_internal( 'delay', $_[1] ); }
125 0     0 1   sub name { return $_[0]->_access_internal( 'name', $_[1] ); }
126              
127             # These are for scheduled task:
128 0     0 1   sub run_every { return $_[0]->_access_internal( 'run_every', $_[1] ); }
129 0     0 1   sub end_at { return $_[0]->_access_internal( 'end_at', $_[1] ); }
130 0     0 1   sub run_times { return $_[0]->_access_internal( 'run_times', $_[1] ); }
131 0     0 1   sub start_at { return $_[0]->_access_internal( 'start_at', $_[1] ); }
132              
133             # Returned when queried a queued task:
134 0     0 1   sub id { return $_[0]->_access_internal( 'id', $_[1] ); }
135 0     0 1   sub project_id { return $_[0]->_access_internal( 'project_id', $_[1] ); }
136 0     0 1   sub code_id { return $_[0]->_access_internal( 'code_id', $_[1] ); }
137 0     0 1   sub status { return $_[0]->_access_internal( 'status', $_[1] ); }
138 0     0 1   sub code_history_id { return $_[0]->_access_internal( 'code_history_id', $_[1] ); }
139 0     0 1   sub code_rev { return $_[0]->_access_internal( 'code_rev', $_[1] ); }
140 0     0 1   sub start_time { return $_[0]->_access_internal( 'start_time', $_[1] ); }
141 0     0 1   sub end_time { return $_[0]->_access_internal( 'end_time', $_[1] ); }
142 0     0 1   sub duration { return $_[0]->_access_internal( 'duration', $_[1] ); }
143 0     0 1   sub updated_at { return $_[0]->_access_internal( 'updated_at', $_[1] ); }
144 0     0 1   sub created_at { return $_[0]->_access_internal( 'created_at', $_[1] ); }
145              
146             sub _access_internal {
147 0     0     my ( $self, $var_name, $var_value ) = @_;
148 0           $log->tracef( '_access_internal(%s, %s)', $var_name, $var_value );
149 0 0         if ( defined $var_value ) {
150 0           $self->{$var_name} = $var_value;
151 0           return $self;
152             }
153             else {
154 0           return $self->{$var_name};
155             }
156             }
157              
158             sub log { ## no critic (Subroutines::ProhibitBuiltinHomonyms)
159 0     0 1   my ($self) = @_;
160 0           $log->tracef('Entering log().');
161              
162 0           my $task_id = $self->id();
163 0           assert_nonblank( $task_id, 'task id not set. Task queued yet?' );
164 0           my $connection = $self->{'connection'};
165 0           my ( $http_status_code, $response_message ) =
166             $connection->perform_iron_action( IO::Iron::IronWorker::Api::IRONWORKER_GET_A_TASKS_LOG(), { '{Task ID}' => $task_id, } );
167 0           $self->{'last_http_status_code'} = $http_status_code;
168              
169 0           $log->tracef( 'Exiting log(): %s', $response_message );
170 0           return $response_message;
171             }
172              
173             sub cancel {
174 0     0 1   my ($self) = @_;
175 0           $log->tracef('Entering cancel().');
176              
177 0           my $task_id = $self->id();
178 0           assert_nonblank( $task_id, 'task id not set. Task queued yet?' );
179 0           my $connection = $self->{'connection'};
180 0           my ( $http_status_code, $response_message ) =
181             $connection->perform_iron_action( IO::Iron::IronWorker::Api::IRONWORKER_CANCEL_A_TASK(), { '{Task ID}' => $task_id, } );
182 0           $self->{'last_http_status_code'} = $http_status_code;
183 0           assert_is( $response_message->{'msg'}, 'Cancelled' );
184              
185 0           $log->tracef( 'Exiting cancel(): %s', 1 );
186 0           return 1;
187             }
188              
189             sub set_progress {
190 0     0 1   my $self = shift;
191             my %params = validate_with(
192             'params' => \@_,
193 0     0     'normalize_keys' => sub { return lc shift },
194 0           'spec' => {
195             'percent' => { type => SCALAR, }, # percentage.
196             'msg' => { type => SCALAR, }, # message.
197             },
198             );
199 0           $log->tracef( 'Entering set_progress(%s)', \%params );
200              
201 0           my $task_id = $self->id();
202 0           assert_nonblank( $task_id, 'task id not set. Task queued yet?' );
203 0           my $connection = $self->{'connection'};
204 0           my ( $http_status_code, $response_message ) = $connection->perform_iron_action(
205             IO::Iron::IronWorker::Api::IRONWORKER_SET_A_TASKS_PROGRESS(),
206             {
207             '{Task ID}' => $task_id,
208             'body' => \%params,
209             }
210             );
211 0           $self->{'last_http_status_code'} = $http_status_code;
212 0           assert_is( $response_message->{'msg'}, 'Progress set' );
213              
214 0           $log->tracef( 'Exiting set_progress(): %s', 1 );
215 0           return 1;
216             }
217              
218             sub retry {
219 0     0 1   my $self = shift;
220             my %params = validate_with(
221             'params' => \@_,
222 0     0     'normalize_keys' => sub { return lc shift },
223 0           'spec' => {
224             'delay' => { type => SCALAR, }, # delay
225             },
226             );
227 0           $log->tracef( 'Entering retry(%s)', \%params );
228              
229 0           my $task_id = $self->id();
230 0           assert_nonblank( $task_id, 'task id not set. Task queued yet?' );
231 0           my $connection = $self->{'connection'};
232 0           my ( $http_status_code, $response_message ) = $connection->perform_iron_action(
233             IO::Iron::IronWorker::Api::IRONWORKER_RETRY_A_TASK(),
234             {
235             '{Task ID}' => $task_id,
236             'body' => \%params,
237             }
238             );
239 0           $self->{'last_http_status_code'} = $http_status_code;
240 0           assert_is( $response_message->{'msg'}, 'Queued up' );
241 0           my $new_task_id = $response_message->{'tasks'}->[0]->{'id'};
242 0           $self->id($new_task_id); # We get a new id.
243              
244 0           $log->tracef( 'Exiting retry(): %s', $new_task_id );
245 0           return $new_task_id;
246             }
247              
248             sub cancel_scheduled {
249 0     0 1   my ($self) = @_;
250 0           $log->tracef('Entering cancel_scheduled().');
251              
252 0           my $task_id = $self->id();
253 0           assert_nonblank( $task_id, 'task id not set. Task scheduled yet?' );
254 0           my $connection = $self->{'connection'};
255 0           my ( $http_status_code, $response_message ) =
256             $connection->perform_iron_action( IO::Iron::IronWorker::Api::IRONWORKER_CANCEL_A_SCHEDULED_TASK(),
257             { '{Schedule ID}' => $task_id, } );
258 0           $self->{'last_http_status_code'} = $http_status_code;
259 0           assert_is( $response_message->{'msg'}, 'Cancelled' );
260              
261 0           $log->tracef( 'Exiting cancel_scheduled(): %s', 1 );
262 0           return 1;
263             }
264              
265             1;
266              
267             __END__
268              
269             =pod
270              
271             =encoding UTF-8
272              
273             =head1 NAME
274              
275             IO::Iron::IronWorker::Task - IronWorker (Online Worker Platform) Client (Task).
276              
277             =head1 VERSION
278              
279             version 0.14
280              
281             =head1 SYNOPSIS
282              
283             Please see IO::Iron::IronWorker::Client for usage.
284              
285             =for stopwords IronWorker API Mikko Koivunalho perldoc CPAN AnnoCPAN ACKNOWLEDGMENTS TODO
286              
287             =for stopwords JSON runtime timestamp io Timestamp Params IronHTTPCallException STDOUT params msg
288              
289             =head1 REQUIREMENTS
290              
291             =head1 SUBROUTINES/METHODS
292              
293             =head2 new
294              
295             Creator function.
296              
297             =head2 Getters/setters
298              
299             Set or get a property.
300             When setting, returns the reference to the object.
301              
302             =over 8
303              
304             =item code_name, The name of the code package to execute for this task (mandatory).
305              
306             =item payload, A string of data to be passed to the worker (usually JSON), can be empty (mandatory).
307              
308             =item priority, The priority queue to run the task in. Valid values are 0, 1, and 2. 0 is the default.
309              
310             =item timeout, The maximum runtime of your task in seconds.
311              
312             =item delay, The number of seconds to delay before actually queuing the task. Default is 0.
313              
314             =item name, Name of task or scheduled task.
315              
316             =item B<These are for scheduled task:>
317              
318             =item run_every, The amount of time, in seconds, between runs
319              
320             =item end_at, The time tasks will stop being queued. Should be a time or a full timestamp (date and time).
321              
322             =item run_times, The number of times a task will run.
323              
324             =item start_at, The time the scheduled task should first be run.
325              
326             =item B<Returned when queried a queued task:>
327              
328             =item id, Task or Scheduled task id.
329              
330             =item project_id, Iron.io project ID.
331              
332             =item code_id, The code package id.
333              
334             =item status, Task execution status.
335              
336             =item code_history_id, Code package revision id?
337              
338             =item code_rev, Code package revision number.
339              
340             =item start_time, Execution started?
341              
342             =item end_time, Execution finished?
343              
344             =item duration, Execution duration?
345              
346             =item updated_at, Timestamp (ISO) of last update.
347              
348             =item created_at, Timestamp (ISO) of creation. E.g. "2012-11-10T18:31:08.064Z"
349              
350             =back
351              
352             =head2 log
353              
354             =over
355              
356             =item Params: [none]
357              
358             =item Return: task log (text/plain).
359              
360             =item Exception: IronHTTPCallException if fails. (IronHTTPCallException: status_code=<HTTP status code> response_message=<response_message>)
361              
362             =back
363              
364             Return the task's log (task's STDOUT).
365              
366             =head2 cancel
367              
368             =over
369              
370             =item Params: [none]
371              
372             =item Return: 1 if successful.
373              
374             =item Exception: IronHTTPCallException if fails. (IronHTTPCallException: status_code=<HTTP status code> response_message=<response_message>)
375              
376             =back
377              
378             Cancel a task.
379              
380             =head2 set_progress
381              
382             =over
383              
384             =item Params (in params hash): percent (integer), msg (free text)
385              
386             =item Return: 1 if successful.
387              
388             =item Exception: IronHTTPCallException if fails. (IronHTTPCallException: status_code=<HTTP status code> response_message=<response_message>)
389              
390             =back
391              
392             Set the progress info to the task.
393              
394             =head2 retry
395              
396             =over
397              
398             =item Params: delay (number of seconds before the task is queued again)
399              
400             =item Return: new task id if successful.
401              
402             =item Exception: IronHTTPCallException if fails. (IronHTTPCallException: status_code=<HTTP status code> response_message=<response_message>)
403              
404             =back
405              
406             Retry a task. A new task id is updated to id field of the object. The id is also returned.
407              
408             =head2 cancel_scheduled
409              
410             =over
411              
412             =item Params: [none]
413              
414             =item Return: 1 if successful.
415              
416             =item Exception: IronHTTPCallException if fails. (IronHTTPCallException: status_code=<HTTP status code> response_message=<response_message>)
417              
418             =back
419              
420             Cancel a task.
421              
422             =head1 AUTHOR
423              
424             Mikko Koivunalho <mikko.koivunalho@iki.fi>
425              
426             =head1 BUGS
427              
428             Please report any bugs or feature requests to bug-io-iron@rt.cpan.org or through the web interface at:
429             http://rt.cpan.org/Public/Dist/Display.html?Name=IO-Iron
430              
431             =head1 COPYRIGHT AND LICENSE
432              
433             This software is copyright (c) 2023 by Mikko Koivunalho.
434              
435             This is free software; you can redistribute it and/or modify it under
436             the same terms as the Perl 5 programming language system itself.
437              
438             The full text of the license can be found in the
439             F<LICENSE> file included with this distribution.
440              
441             =cut