package Step::Base; use v5.10.1; use threads; use threads::shared; use namespace::autoclean; #use feature qw( switch ); use Moose; has 'name' => ( is => 'ro', isa => 'Str', required => 1, ); has 'code_to_run' => ( is => 'ro', isa => 'Str', required => 1, ); has 'args' => ( is => 'ro', isa => 'ArrayRef', ); has 'return_code' => ( is => 'rw', isa => 'ArrayRef', ); has 'state' => ( is => 'rw', isa => 'Str', default => 'Created', ); has 'success' => ( is => 'rw', isa => 'Int', ); has 'error' => ( is => 'rw', isa => 'Str', ); has 'time_started' => ( is => 'rw', isa => 'Int', ); has 'time_finished' => ( is => 'rw', isa => 'Int', ); has 'success' => ( is => 'rw', isa => 'Int', ); has 'predecessors' => ( is => 'ro', isa => 'ArrayRef', ); has 'thr' => ( is => 'rw', isa => 'Object', ); has 'steps' => ( is => 'ro', ); sub run { my ( $self, ) = @_; $self->time_started(time); my $thr = threads->create( $self->code_to_run, $self->args ); if ( $thr->error ) { $self->state('Abended'); $self->error(@$); $self->time_finished(time); $self->success(0); return( 0 ); } else { $self->thr($thr); $self->success(1); $self->state('Running'); return( 1 ); } } ## ---------- end sub run sub ready { my ( $self, ) = @_; return(0) unless $self->state eq 'Created'; $self->_predecessors_complete( $self->predecessors ) ? return(1) : return(0); } ## ---------- end sub ready sub running { my ( $self, ) = @_; $self->state eq "Running" ? return(1) : return(0) } ## ---------- end sub running sub done { my ( $self, ) = @_; # check to see if thread is ready to join and join if it is given( $self->state ) { when( 'Running' ) { my @joinable = threads->list(threads::joinable); foreach my $thr (@joinable) { next unless ( $thr->tid == $self->thr->tid ); my $rc = $thr->join; if ( $rc->{success} ) { $self->state('Completed'); } else { $self->state('Abended'); my $err_msg; if ( my $thread_error = $thr->error ) { $err_msg = "$thread_error\n" } $err_msg .= $rc->{err_msg}; $self->error($err_msg); } $self->time_finished(time); return (1); } return (0); } when( 'Completed' ) { return(1); } when( 'Abended' ) { return(1); } when( 'Cancelled' ) { return(1); } default { return (0); } } } ## ---------- end sub done sub _predecessors_complete { my ( $self, $predecessors ) = @_; foreach my $p ( @{ $predecessors } ) { #given( $main::steps->{ $p }->state ) { given( $self->steps->{ $p }->state ) { when ("Complete") { next; } when ("Created") { return(0); } when ("Running") { return(0); } when ("Cancelled") { $self->state("Cancelled"); return(0); } when ("Abended") { $self->state("Cancelled"); return(0); } } } return ( 1 ); } ## ---------- end sub _predecessors_status sub time_elapsed { my ( $self, ) = @_; given( $self->state ) { when( 'Running' ) { return ( time - $self->time_started ); } when( 'Completed' ) { return ( $self->time_finished - $self->time_started ); } default { return (undef); } } } ## ---------- end sub time_elapsed 1; __PACKAGE__->meta->make_immutable;