package PGF::Utilities::JobManager; =head1 NAME PGF::Utilities::JobManager; =head1 VERSION $Revision: 1.3 $ $Date: 2008-09-06 00:31:02 $ =head1 SYNOPSIS use PGF::Utilities::JobManager->new; my $jm = PGF::Utilities::JobManager->new(); $jm->setMaxNumberOfParallelProcesses($numberOfParallelProcesses); $jm->setLogOutFile($file); # optional; print stdout to log file $jm->setLogErrorFile($file); # optional; print stderr to log file $jm->setLogOutFileAppend($file); # optional; append stdout to log file; $jm->setLogErrorFileAppend($file); # optional; append stderr to log file; $jm->turnOnDebugging; # optional $jm->turnOffDebugging; #optional $jm->parallel(@systemCommands); =head1 DESCRIPTION This module uses fork to run jobs in parallel on a single server. Logging is performed via the Logger.pm module for Polisher. =head1 AUTHOR(S) Stephan Trong =head1 COPYRIGHT DOE Joint Genome Institute Microbial Genomics Copyright (C) 2008 The Regents of the University of California All rights reserved. NOTICE: The Government is granted for itself and others acting on its behalf a paid-up, nonexclusive irrevocable worldwide license in this data to reproduce, prepare derivative works, and perform publicly and display publicly. Beginning five (5) years after permission to assert copyright is granted, subject to two possible five year renewals, the Government is granted for itself and others acting on its behalf a paid-up, non-exclusive, irrevocable worldwide license in this data to reproduce, prepare derivative works, distribute copies to the public, perform publicly and display publicly, and to permit others to do so. NEITHER THE UNITED STATES NOR THE UNITED STATES DEPARTMENT OF ENERGY, NOR ANY OF THEIR EMPLOYEES, MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LEGAL LIABILITY OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR USEFULNESS OF ANY INFORMATION, APPARATUS, PRODUCT, OR PROCESS DISCLOSED, OR REPRESENTS THAT ITS USE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS. =head1 HISTORY =over 4 =item * S.Trong 2008/08/18 Creation =item * =back =cut use strict; use warnings; use Carp; use Carp qw(cluck); use threads; use FileHandle; use FindBin; use lib "$FindBin::RealBin/../lib"; use Parallel::ForkManager; use PGF::Utilities::RunProcess qw(runProcess); use PGF::Utilities::Logger; #============================================================================# sub new { my $class = shift; my %params = @_; # %params may be: # debug=>0|1 turns on/off printing of debugging. May also use # turnOnDebugging/turnOffDebugging methods instead. my $self = {}; $self->{_commandStatus} = []; $self->{_debug} = defined $params{-debug} ? $params{debug} : 0; $self->{_maxNumberOfParallelProcesses} = 1; $self->{_logOutFile} = ''; $self->{_logErrorFile} = ''; $self->{_appendToLogOutFile} = 0; $self->{_appendToLogErrorFile} = 0; bless $self, $class; return $self; } #============================================================================# sub setLogOutFile { my $self = shift; $self->{_logOutFile} = shift; } #============================================================================# sub setLogErrorFile { my $self = shift; $self->{_logErrorFile} = shift; } #============================================================================# sub setLogOutFileAppend { my $self = shift; $self->{_logOutFile} = shift; $self->{_appendToLogOutFile} = 1; } #============================================================================# sub setLogErrorFileAppend { my $self = shift; $self->{_logErrorFile} = shift; $self->{_appendToLogErrorFile} = 1; } #============================================================================# sub turnOnDebugging { my $self = shift; $self->{_debug} = 1; } #============================================================================# sub turnOffDebugging { my $self = shift; $self->{_debug} = 0; } #============================================================================# sub setMaxNumberOfParallelProcesses { my $self = shift; my $maxNumberOfParallelProcesses = shift; $self->{_maxNumberOfParallelProcesses} = $maxNumberOfParallelProcesses; } #============================================================================# sub parallel { # Run one or more jobs in asynchronous mode. # my $self = shift; my @commands = @_; my $maxNumberOfProcesses = $self->{_maxNumberOfParallelProcesses}; my $objForkManager = new Parallel::ForkManager($maxNumberOfProcesses); print "[P] Number of jobs found: ",scalar(@commands),"\n" if $self->{_debug}; foreach my $command (@commands) { $self->logOutput($command) if $self->{_logOutFile}; my $pid = $objForkManager->start and next; print "Running $command\n" if $self->{_debug}; $self->_runJob($command); $objForkManager->finish; } $objForkManager->wait_all_children; } #============================================================================# sub _runJob { # Execute job. my $self = shift; my $command = shift; my %status = runProcess($command, {-checkExecutable=>0,-stdout=>0, -stderr=>1} ); if ( $status{exitCode} ) { my $errMsg = "$command generated an error:\n"; $errMsg .= $status{stderrMessage}."\n" if length $status{stderrMessage}; $self->logError($errMsg) if $self->{_logErrorFile}; print STDERR $errMsg; } } #============================================================================# sub logOutput { my $self = shift; my $message = shift; my $objLogger = PGF::Utilities::Logger->new(); if ( $self->{_appendToLogOutFile} ) { $objLogger->setLogOutFileAppend($self->{_logOutFile}); } else { $objLogger->setLogOutFile($self->{_logOutFile}); } $objLogger->logOut($message); } #============================================================================# sub logError { my $self = shift; my $message = shift; my $objLogger = PGF::Utilities::Logger->new(); if ( $self->{_appendToLogErrorFile} ) { $objLogger->setLogOutFileAppend($self->{_logErrorFile}); } else { $objLogger->setLogOutFile($self->{_logErrorFile}); } $objLogger->logError($message); } #============================================================================# sub _getCurrentDateAndTime { # Returns current date and time in format: # 'MM-DD-YYYY HH24:MI:SS' my ($sec,$min,$hour,$day,$mon,$year) = localtime(time); $mon++; $year+=1900; my $time = sprintf( "%02d-%02d-%04d %02d:%02d:%02d", $mon,$day,$year,$hour,$min,$sec ); return $time; } #============================================================================# 1;