@@ -199,16 +199,30 @@ def select_runs(self):
199
199
result .append (BPRun (self .batch_id , run_id , bstart , bend , command ))
200
200
return result
201
201
202
- def select_jobs (self , by_status = None , by_run = None ):
202
+ def select_job_count (self ):
203
+ '''Return the # of jobs with links to the batch through the run tbl'''
204
+ cmd = """select count('x') from run r where r.batch_id = %d
205
+ and exists (select 'x' from job_status js
206
+ where js.run_id = r.run_id)""" % self .batch_id
207
+ with bpcursor () as cursor :
208
+ cursor .execute (cmd )
209
+ return cursor .fetchone ()[0 ]
210
+
211
+ def select_jobs (self , by_status = None , by_run = None , page_size = None ,
212
+ first_item = None ):
203
213
'''Get jobs with one of the given statuses
204
214
205
- args - the statuses to fetch
215
+ by_status - a sequence of status names to search for (default = all)
216
+ by_run - a run ID to search for (Default = all runs
217
+ page_size - return at most this many items (default all)
218
+ first_item - the one-based index of the first item on the page
219
+ (default first)
206
220
207
221
returns a sequence of run, job, status tuples
208
222
'''
209
223
cmd = """
210
224
select rjs.run_id, rjs.bstart, rjs.bend, rjs.command, rjs.job_id,
211
- js.status
225
+ js.status, @rownum:=@rownum+1 as rank
212
226
from (select r.run_id as run_id, r.bstart as bstart, r.bend as bend,
213
227
r.command as command, js.job_id as job_id,
214
228
max(js.created) as js_created, j.created as j_created
@@ -222,6 +236,7 @@ def select_jobs(self, by_status=None, by_run=None):
222
236
join job_status js
223
237
on rjs.run_id = js.run_id and rjs.job_id = js.job_id
224
238
and rjs.js_created = js.created
239
+ join (select @rownum:=0) as ranktbl
225
240
""" % self .batch_id
226
241
clauses = []
227
242
if by_status is not None :
@@ -230,10 +245,13 @@ def select_jobs(self, by_status=None, by_run=None):
230
245
clauses .append ("rjs.run_id = %d" % by_run )
231
246
if len (clauses ) > 0 :
232
247
cmd += " where " + " and " .join (clauses )
248
+ if first_item is not None and page_size is not None :
249
+ cmd = "select * from (%s) cmd where cmd.rank between %d and %d" % (
250
+ cmd , first_item , first_item + page_size - 1 )
233
251
with bpcursor () as cursor :
234
252
cursor .execute (cmd )
235
253
result = []
236
- for run_id , bstart , bend , command , job_id , status in cursor :
254
+ for run_id , bstart , bend , command , job_id , status , rank in cursor :
237
255
run = BPRun (self .batch_id , run_id , bstart , bend , command )
238
256
job = BPJob (run_id , job_id )
239
257
result .append ((run , job , status ))
@@ -263,26 +281,42 @@ def get_job_name(self):
263
281
def get_file_name (self ):
264
282
raise NotImplemented ("Use BPRun or BPSQLRun" )
265
283
284
+ @staticmethod
285
+ def select (run_id ):
286
+ '''Select a BPRun or BPSQLRun given a run_id
287
+
288
+ '''
289
+ with bpcursor () as cursor :
290
+ cmd = """select rb.run_type
291
+ from run_base rb where run_id=%d""" % run_id
292
+ cursor .execute (cmd )
293
+ run_type = cursor .fetchone ()[0 ]
294
+ if run_type == RT_SQL :
295
+ return BPSQLRun .select_by_run_id (run_id )
296
+ return BPRun .select (run_id )
297
+
266
298
def select_jobs (self , by_status = None ):
267
299
cmd = """
268
- select rjs.job_id, js.status
269
- from (select js.job_id as job_id, max(js.created) as created
270
- from job_status js
271
- where js.run_id = %d
272
- group by job_id) js1
273
- join job_status js1
274
- on js1.run_id = js2.run_id and js1.job_id = js2.job_id
275
- and js1.created = js2.created
276
- """ % self .run_id
300
+ select js.job_id, js.status
301
+ from job_status js
302
+ join job j on js.job_id = j.job_id and js.run_id = j.run_id
303
+ where js.created in
304
+ (select max(js2.created) from job_status js2
305
+ where js2.run_id = %d
306
+ group by js2.job_id)
307
+ and j.created in
308
+ (select max(j2.created) from job j2 where j2.run_id = %d)
309
+ and j.run_id = %d
310
+ """ % (self .run_id , self .run_id , self .run_id )
277
311
clauses = []
278
312
if by_status is not None :
279
- cmd += " where status in ( '%s' )" % ("','" .join (args ))
313
+ cmd += " and status in ( '%s' )" % ("','" .join (args ))
280
314
with bpcursor () as cursor :
281
315
cursor .execute (cmd )
282
316
result = []
283
317
for job_id , status in cursor :
284
- job = BPJob (run_id , job_id )
285
- result .append (job , status )
318
+ job = BPJob (self . run_id , job_id )
319
+ result .append (( job , status ) )
286
320
return result
287
321
288
322
class BPRun (BPRunBase ):
@@ -343,6 +377,8 @@ def select_by_sql_filename(batch, sql_filename):
343
377
where rs.sql_filename = %s
344
378
and rb.run_type = 'SQL'
345
379
and rb.batch_id = %s""" , [sql_filename , batch .batch_id ])
380
+ if cursor .rowcount == 0 :
381
+ return None
346
382
run_id , command = cursor .fetchone ()
347
383
return BPSQLRun (batch .batch_id , int (run_id ), sql_filename , command )
348
384
@@ -422,7 +458,7 @@ def run_one(my_batch, run, cwd = None):
422
458
cwd - the working directory for the command. Defaults to my_batch.cpcluster
423
459
'''
424
460
assert isinstance (my_batch , BPBatch )
425
- assert isinstance (run , BPRun )
461
+ assert isinstance (run , BPRunBase )
426
462
txt_output = text_file_directory (my_batch )
427
463
if not os .path .exists (txt_output ):
428
464
os .mkdir (txt_output )
@@ -438,6 +474,15 @@ def run_one(my_batch, run, cwd = None):
438
474
script = """#!/bin/sh
439
475
export RUN_ID=%d
440
476
""" % run .run_id
477
+ #
478
+ # A work-around if HOME has been defined differently on the host
479
+ #
480
+ script += """
481
+ if [ ! -z "$SGE_O_HOME" ]; then
482
+ export HOME="$SGE_O_HOME"
483
+ echo "Set home to $HOME"
484
+ fi
485
+ """
441
486
#
442
487
# This is a REST PUT to JobStatus.py to create the job record
443
488
#
@@ -456,9 +501,14 @@ def run_one(my_batch, run, cwd = None):
456
501
if run .source_cpenv :
457
502
script += '. %s\n ' % os .path .join (PREFIX , "bin" , "cpenv.sh" )
458
503
#
504
+ # set +e allows the command to error-out without ending this script.
505
+ # This lets us capture the error status.
506
+ #
507
+ script += "set +e\n "
508
+ #
459
509
# Run CellProfiler
460
510
#
461
- script += run .command
511
+ script += run .command + " \n "
462
512
#
463
513
# Figure out the status from the error code
464
514
#
@@ -467,6 +517,10 @@ def run_one(my_batch, run, cwd = None):
467
517
script += "else\n JOB_STATUS=%s\n " % JS_ERROR
468
518
script += "fi\n "
469
519
#
520
+ # Go back to erroring-out
521
+ #
522
+ script += "set -e\n "
523
+ #
470
524
# Set the status based on the result from CellProfiler
471
525
# Use CURL again
472
526
#
@@ -506,13 +560,20 @@ def cellprofiler_command(my_batch, bstart, bend):
506
560
def kill_one (run ):
507
561
batch = BPBatch ()
508
562
batch .select (run .batch_id )
509
- jobs = batch .select_jobs (by_status = [JS_RUNNING ], by_run = run .run_id )
510
- bputilities .kill_jobs ([job .job_id for job in jobs ])
563
+ jobs = batch .select_jobs (by_status = [JS_SUBMITTED , JS_RUNNING ],
564
+ by_run = run .run_id )
565
+ bputilities .kill_jobs ([job .job_id for run , job , status in jobs ])
566
+ for job in jobs :
567
+ job .update_status (JS_ABORTED )
568
+
569
+ def kill_job (job ):
570
+ bputilities .kill_jobs ([job .job_id ])
571
+ job .update_status (JS_ABORTED )
511
572
512
573
def kill_batch (batch_id ):
513
574
batch = BPBatch ()
514
575
batch .select (batch_id )
515
- jobs = batch .select_jobs (by_status = [JS_RUNNING ])
576
+ jobs = batch .select_jobs (by_status = [JS_SUBMITTED , JS_RUNNING ])
516
577
bputilities .kill_jobs ([job .job_id for run , job , status in jobs ])
517
578
for run , job , status in jobs :
518
579
job .update_status (JS_ABORTED )
@@ -541,6 +602,29 @@ def text_file_directory(batch):
541
602
def script_file_directory (batch ):
542
603
return os .path .join (batch .data_dir , "job_scripts" )
543
604
605
+ def batch_script_file (script_file ):
606
+ '''The name of the SQL script file modded to pull in all of the .CSV files
607
+
608
+ script_file - the name of the original file
609
+ '''
610
+ return "batch_%s" % script_file
611
+
612
+ def batch_script_directory (batch ):
613
+ '''The directory housing the modded SQL files
614
+
615
+ batch - batch in question
616
+ script_file - the name of the original file
617
+
618
+ Note: this can't be in batch.data_dir because
619
+ it would be automagically scanned and
620
+ picked up by sql_jobs
621
+ '''
622
+ return os .path .join (batch .data_dir , "sql_scripts" )
623
+
624
+ def batch_script_path (batch , script_file ):
625
+ return os .path .join (batch_script_directory (batch ),
626
+ batch_script_file (script_file ))
627
+
544
628
def script_file_path (batch , run ):
545
629
return os .path .join (script_file_directory (batch ),
546
630
"run_%s.sh" % run .get_file_name ())
@@ -577,7 +661,7 @@ def GetCPUTime(batch, run):
577
661
run - the job's last run
578
662
'''
579
663
assert isinstance (batch , BPBatch )
580
- assert isinstance (run , BPRun )
664
+ assert isinstance (run , BPRunBase )
581
665
with bpcursor () as cursor :
582
666
cmd = """
583
667
select unix_timestamp(js2.created)-unix_timestamp(js1.created) as cputime
0 commit comments