File Coverage

blib/lib/Schedule/SGE/Run.pm
Criterion Covered Total %
statement 9 103 8.7
branch 0 52 0.0
condition n/a
subroutine 3 16 18.7
pod 11 11 100.0
total 23 182 12.6


line stmt bran cond sub pod time code
1             # Schedule::SGE::Run
2              
3             # POD docs
4              
5             =head1 Schedule::SGE::Run
6              
7             Submit jobs to the Sun Grid Engine (tm, probably), and check on the status of the engine. You should not use this method directly, rather you should use the Schedule::SGE method that inherits from this, then all the methods herein are available to you.
8              
9             =head1 AUTHOR
10              
11             Rob Edwards (rob@salmonella.org)
12             3/24/05
13              
14             =cut
15              
16             package Schedule::SGE::Run;
17 1     1   5 use strict;
  1         2  
  1         32  
18 1     1   5 use Exporter;
  1         1  
  1         33  
19              
20 1     1   4 use vars qw(@ISA @EXPORT_OK);
  1         1  
  1         1189  
21             @ISA = qw(Schedule::SGE Exporter);
22             @EXPORT_OK = qw(command execute environment name project output_file error_file use_cwd notify mailto job_id);
23             our $VERSION = '0.01';
24              
25             =head2 command()
26              
27             Get or set the command that will be queued to by run
28              
29             =cut
30              
31             sub command {
32 0     0 1   my ($self, @jobs)=@_;
33 0 0         if ($jobs[0]) {
34 0           $self->{'command'} = join " ", @jobs;
35 0           $self->{'ran'}=0;
36             }
37 0           return $self->{'command'};
38             }
39              
40              
41             =head2 execute()
42              
43             Run the command and return the queue id number.
44              
45             The queue number is the location of the job in the queue, and you can cehck on that with queue_status
46              
47             =cut
48              
49             sub execute {
50 0     0 1   my ($self) = @_;
51             #return $self::Run->_run();
52 0           return &_run($self);
53             }
54              
55              
56             =head2 environment()
57              
58             Get and set the environment variables for Schedule::SGE. The variables that we need to care about are, and the default variables for my system are:
59             SGE_CELL orionmulti
60             SGE_EXECD_PORT 537
61             SGE_QMASTER_PORT 536
62             SGE_ROOT /opt/sge
63              
64             my $hashref=$sge->environment(\%vars);
65              
66             =cut
67              
68             sub environment {
69 0     0 1   my ($self, $hash)=@_;
70 0           my $return;
71 0           foreach my $var (qw[SGE_CELL SGE_EXECD_PORT SGE_QMASTER_PORT SGE_ROOT]) {
72 0 0         if ($hash->{$var}) {$ENV{$var}=$hash->{$var}}
  0            
73 0           $return->{$var}=$ENV{$var};
74             }
75 0           return $return;
76             }
77            
78             =head2 name()
79              
80             Get or set the name of the job used by Schedule::SGE.
81              
82             =cut
83              
84             sub name {
85 0     0 1   my ($self, $val)=@_;
86 0 0         if ($val) {
87 0 0         unless ($val =~ /^[a-zA-Z]/) {
88 0           print STDERR "Name must start with a letter. Name is now a$val\n";
89 0           $val="a".$val;
90             }
91 0 0         if ($val =~ / /) {
92 0           $val =~ s/ /_/g;
93 0           print STDERR "Name can not have spaces in it. Name is now $val\n";
94             }
95 0 0         if (length($val) > 10) {
96 0           $val=substr($val, 0, 10);
97 0           print STDERR "Name is truncated to 10 letters. Name is now $val\n";
98             }
99 0           $self->{'name'}=$val;
100             }
101 0           return $self->{'name'};
102             }
103              
104             =head2 project()
105              
106             Get or set the project used by Schedule::SGE.
107              
108             =cut
109              
110             sub project {
111 0     0 1   my ($self, $val)=@_;
112 0 0         if ($val) {
113 0           $val =~ s/ /_/g;
114 0           $self->{'project'}=$val;
115             }
116 0           return $self->{'project'};
117             }
118              
119             =head2 output_file()
120              
121             Get or set the filename that will be used for the STDOUT
122              
123             =cut
124              
125             sub output_file {
126 0     0 1   my ($self, $val)=@_;
127 0 0         if ($val) {
128 0           $self->{'output_file'}=$val;
129             }
130 0           return $self->{'output_file'};
131             }
132              
133              
134             =head2 error_file()
135              
136             Get or set the filename that will be used for the STDERR
137              
138             =cut
139              
140             sub error_file {
141 0     0 1   my ($self, $val)=@_;
142 0 0         if ($val) {
143 0           $self->{'error_file'}=$val;
144             }
145 0           return $self->{'error_file'};
146             }
147              
148              
149             =head2 use_cwd()
150              
151             Boolean whether to set the cwd directory. NOTE: By default this is set to true, and you have to turn it off if you don't want it.
152              
153             =cut
154              
155             sub use_cwd {
156 0     0 1   my ($self, $val)=@_;
157 0 0         if (!defined $self->{'cwd'}) {$self->{'cwd'}=1}
  0            
158 0 0         if (defined $val) {
159 0           $self->{'cwd'}=$val;
160             }
161 0           return $self->{'cwd'};
162             }
163              
164             =head2 notify()
165              
166             Get or set whether the notify flag is set
167              
168             =cut
169              
170             sub notify {
171 0     0 1   my ($self, $val)=@_;
172 0 0         if (defined $val) {
173 0           $self->{'notify'}=$val;
174             }
175 0           return $self->{'notify'};
176             }
177              
178             =head2 mailto()
179              
180             Email address to send the notify mail to
181              
182             =cut
183              
184             sub mailto {
185 0     0 1   my ($self, $val)=@_;
186 0 0         if ($val) {
187 0           $self->{'mailto'}=1;
188             }
189 0           return $self->{'cwd'};
190             }
191              
192              
193             =head2 job_id()
194              
195             The ID of the job that is submitted. This is only available after the command has begun, and is the ID of your job in the queue. Returns false if the job has not been executed or there was an error with the execution.
196              
197             =cut
198              
199             sub job_id {
200 0     0 1   my ($self)=@_;
201 0           return $self->{'job_id'};
202             }
203              
204             =head2 _run()
205              
206             An internal method to execute the command
207              
208             =cut
209              
210             sub _run {
211 0     0     my ($self)=@_;
212 0 0         return if ($self->{'ran'}); # we already run
213 0           $self->{'ran'}=1;
214            
215 0           my $pipe = $self->executable('qsub');
216 0 0         &_dieout('qsub') unless ($pipe);
217 0 0         &_dieout('command') unless ($self->{'command'});
218            
219 0           my %tags=(
220             'name' => ' -N ',
221             'project' => ' -P ',
222             'mailto' => ' -M ',
223             'output_file' => ' -o ',
224             'error_file' => ' -e ',
225             );
226              
227 0 0         foreach my $tag (keys %tags) {if ($self->{$tag}) {$pipe .= $tags{$tag}.$self->{$tag}}}
  0            
  0            
228              
229 0 0         if ($self->use_cwd) {$pipe .= " -cwd"}
  0            
230 0 0         if ($self->notify) {$pipe .= " -notify"}
  0            
231              
232              
233 0           my $command=$self->{'command'};
234 0 0         if ($self->{'verbose'}) {print STDERR "OPENING PIPE: $pipe\nSENDING JOB THROUGH PIPE: $command\n"}
  0            
235 0 0         open(QSUB, "|$pipe > /tmp/$$.out 2>&1") || die "Can't open the pipe to submit jobs to";
236 0           print QSUB $command, "\n";
237 0           close QSUB;
238              
239 0 0         return 0 unless (-e "/tmp/$$.out");
240              
241 0 0         open (IN, "/tmp/$$.out") || die "Can't open /tmp/$$.out even though everything appeared to work fine";
242 0           my $line=;
243 0           close IN;
244 0           $line =~ /Your job (\d+)/i;
245 0           my $jobnumber=$1;
246 0 0         if ($jobnumber) {
247 0           unlink("/tmp/$$.out");
248 0           $self->{'job_id'}=$jobnumber;
249 0           return $jobnumber;
250             }
251             else {
252 0           print STDERR "WARNING: No job number. This message was received:\n$line";
253 0           return 0;
254             }
255             }
256              
257              
258             =head2 _dieout()
259              
260             Die nicely, with some kind of warning
261              
262             =cut
263              
264             sub _dieout {
265 0     0     my ($self, $val)=@_;
266 0 0         if ($val eq "command") {
    0          
267 0           print STDERR <
268              
269             You did not specify a command to run and so we are cowardly quitting.
270              
271             EOF
272             }
273             elsif ($val eq "qsub") {
274 0           print STDERR <
275              
276             $0 could not find a $val executable. Please check to make sure that it is in your path, and you are running SGE.
277              
278             EOF
279             }
280             else {
281 0           print STDERR <
282              
283             $0 died out for an unexplained reason. Sorry.
284              
285             EOF
286             }
287              
288 0           exit(-1);
289             }
290              
291              
292              
293             1;