Repository: DataBiosphere/toil

Issue:
Failed job exception double prints job store id



Discussion:

Resolving patch:
diff --git a/src/toil/batchSystems/singleMachine.py b/src/toil/batchSystems/singleMachine.py
--- a/src/toil/batchSystems/singleMachine.py
+++ b/src/toil/batchSystems/singleMachine.py
@@ -120,33 +120,6 @@ def __init__(self, config, maxCores, maxMemory, maxDisk):
             self.workerThreads.append(worker)
             worker.start()
 
-    def _getDebugCmd(self, jobCommand):
-        """Calculate useful debugging command line, handling CWL runs.
-
-        Tries to print out underlying CWL base command being run if possible,
-        otherwise defaulting to the toil jobCommand.
-        """
-        debug_cmd = jobCommand
-        cmd_args = jobCommand.split()
-        if len(cmd_args) == 3 and cmd_args[0] == "_toil_worker":
-            _, job_store_locator, job_store_id = cmd_args
-            if job_store_locator.startswith("file:") or os.path.exists(job_store_locator):
-                import cPickle
-                import marshal as pickler
-                job_store_locator = job_store_locator.replace("file:", "")
-                job_cmd_file = os.path.join(job_store_locator, "tmp", job_store_id, "job")
-                with open(job_cmd_file) as in_handle:
-                    job = pickler.load(in_handle)
-                if job.get("command"):
-                    command_parts = job["command"].split()
-                    input_pickle_file = os.path.join(job_store_locator, "tmp", command_parts[1])
-                    with open(input_pickle_file) as in_handle:
-                        input = cPickle.load(in_handle)
-                    if (hasattr(input, "cwltool") and hasattr(input.cwltool, "tool")
-                            and "baseCommand" in input.cwltool.tool):
-                        debug_cmd = " ".join(input.cwltool.tool["baseCommand"])
-        return debug_cmd
-
     # Note: The input queue is passed as an argument because the corresponding attribute is reset
     # to None in shutdown()
 
@@ -168,7 +141,6 @@ def worker(self, inputQueue):
                                   jobCores)
                         with self.coreFractions.acquisitionOf(coreFractions):
                             with self.disk.acquisitionOf(jobDisk):
-                                log.debug("Executing command: '%s'.", self._getDebugCmd(jobCommand))
                                 startTime = time.time() #Time job is started
                                 with self.popenLock:
                                     popen = subprocess.Popen(jobCommand,
diff --git a/src/toil/cwl/cwltoil.py b/src/toil/cwl/cwltoil.py
--- a/src/toil/cwl/cwltoil.py
+++ b/src/toil/cwl/cwltoil.py
@@ -221,12 +221,22 @@ def __init__(self, tool, cwljob, **kwargs):
         builder.timeout = 0
         builder.resources = {}
         req = tool.evalResources(builder, {})
+        self.cwltool = tool
+        # pass the default of None if basecommand is empty
+        unitName = self.cwltool.tool.get("baseCommand", None)
+        if isinstance(unitName, (list, tuple)):
+            unitName = ' '.join(unitName)
         super(CWLJob, self).__init__(cores=req["cores"],
-                     memory=(req["ram"]*1024*1024),
-                     disk=((req["tmpdirSize"]*1024*1024) + (req["outdirSize"]*1024*1024)))
+                                     memory=(req["ram"]*1024*1024),
+                                     disk=((req["tmpdirSize"]*1024*1024) + (req["outdirSize"]*1024*1024)),
+                                     unitName=unitName)
         #super(CWLJob, self).__init__()
-        self.cwltool = tool
         self.cwljob = cwljob
+        try:
+            self.jobName = str(self.cwltool.tool['id'])
+        except KeyError:
+            # fall back to the Toil defined class name if the tool doesn't have an identifier
+            pass
         self.executor_options = kwargs
 
     def run(self, fileStore):
diff --git a/src/toil/leader.py b/src/toil/leader.py
--- a/src/toil/leader.py
+++ b/src/toil/leader.py
@@ -48,7 +48,7 @@ def __init__(self, jobStoreLocator, failedJobs, jobStore):
             for jobNode in failedJobs:
                 job = jobStore.load(jobNode.jobStoreID)
                 if job.logJobStoreFileID:
-                    msg += "\n=========> Failed job %s %s\n" % (jobNode, jobNode.jobStoreID)
+                    msg += "\n=========> Failed job %s \n" % jobNode
                     with job.getLogFileHandle(jobStore) as fH:
                         msg += fH.read()
                     msg += "<=========\n"
@@ -187,8 +187,7 @@ def run(self):
                      ("successfully" if len(self.toilState.totalFailedJobs) == 0 else ("with %s failed jobs" % len(self.toilState.totalFailedJobs))))
 
         if len(self.toilState.totalFailedJobs):
-            logger.info("Failed jobs at end of the run: %s", self.toilState.totalFailedJobs)
-
+            logger.info("Failed jobs at end of the run: %s", ' '.join(str(job) for job in self.toilState.totalFailedJobs))
         # Cleanup
         if len(self.toilState.totalFailedJobs) > 0:
             raise FailedJobsException(self.config.jobStore, self.toilState.totalFailedJobs, self.jobStore)


Test patch: