sub _replicate{ my $ref = shift; my $logger = get_logger(); print "Starting replication of dependency files", $/; $logger->info("Starting replication of dependency files"); foreach my $sc(@{$ref}){ next unless (defined $sc); mkdir($LOG_FOLDER."/".$sc->{sc_name}); $logger->info("\tScenario: ".$sc->{sc_name}); $logger->info("\tLatest Dependencies: ".$sc->{total_dep}." of size "._get_readable_size($sc->{total_size})); my @thr_arr = (); foreach my $robj(@{$sc->{rsync}}){ # I will add a key to this datastructure, to check whether thread is joinnable or it is still running? $robj->{thr} => 'running'; my $th = threads->create(\&worker, $robj); $logger->info("\tThread-".$th->tid.", Total files: ".$robj->{statistics}->{total_files}.", Size: "._get_readable_size($robj->{statistics}->{size})."[".$robj->{statistics}->{size}."B]"); $logger->info("\tcmd: ".join("", @{$robj->{elements}})); push @thr_arr, $th->tid; } $logger->info("\twaiting for threads to finish its job..."); # 3rd try foreach my $k(0..$#thr_arr){ # lets check tid and then access the thread object! print $k," ",$sc->{rsync}->[$k]->{thr}, $/; if ($sc->{rsync}->[$k]->{thr} eq 'running'){# if not, thread might have died and we try to acces the mem. which is deallocated after thread's death my $t = $thr_arr[$k]; my $th = threads->object($t); $th->join() if ($th); } } # 2nd try # map{ # my $th = $_; # just a blind belief whether this might cause 'Segmentation fault', hence the check. But here may, the thread object im referring might have been deallocated due to death of thread, hence i get 'Segmentation fault' .... ? # my $k = $th->join if($th); # }@thr_arr; # 1st try # May be the thread objects returned by threads->list are unjoined, but are they joinnable? no clue...! #map {my $k = $_->join} threads->list; $logger->info("\tFinished replicating dependencies of ".$sc->{sc_name}); } } sub worker{ my $robj = shift; my ($rsync, $server, $from, $to) = @{$robj->{elements}}; my $alt_server = $RSYNC_CONN_STR_2; print "Thread-".threads->self->tid." running"; my $i = 0; while(++$i <= $MAX_REPL_ATTEMPT){ #$logger->info("\t\t[Attempt-".$i."]Thread-".threads->self->tid." executing [".$rsync_cmd."]"); #$logger->info("\t\t\tTotal files: ".$robj->{statistics}->{total_files}.", Size: "._get_readable_size($robj->{statistics}->{size})."[".$robj->{statistics}->{size}."B]"); my $rsync_cmd = $rsync.$server.$from.$to; `$rsync_cmd`; if ($?){ # because of connection refusal from server, command fails $robj->{status} = "Completed with error!"; $rsync_cmd = $rsync.$server.$from.$to; $server = ($i%2) ? $RSYNC_CONN_STR_1 : $RSYNC_CONN_STR_2; # just a small trick to use other port on the same server for connection #$logger->error("ERROR: Thread-".threads->self->tid." says, replication Attempt-".$i." failed, trying again after 2 mins."); sleep(120); }else{ $robj->{status} = "Completed"; last; } } $robj->{thr} = 'done'; my $etime = time; my $spent_time = $etime - $stime; my $logger = get_logger(); $logger->info("\t\t[Attempt-".$i."]Thread-".threads->self->tid." took "._format_spent_time($spent_time)." time"); }