""" Create and send a combined request for any pending operations at the end of a job: * fileReport (for the transformation) * jobReport (for jobs) * accounting * request (for failover) """ from __future__ import absolute_import from __future__ import division from __future__ import print_function from DIRAC import gLogger from DIRAC.TransformationSystem.Client import TransformationFilesStatus from DIRAC.Workflow.Modules.ModuleBase import ModuleBase, GracefulTermination class FailoverRequest(ModuleBase): ############################################################################# def __init__(self): """Module initialization.""" self.log = gLogger.getSubLogger("FailoverRequest") super(FailoverRequest, self).__init__(self.log) ############################################################################# def _resolveInputVariables(self): """By convention the module input parameters are resolved here.""" super(FailoverRequest, self)._resolveInputVariables() super(FailoverRequest, self)._resolveInputStep() def _initialize(self): """checks if is to do, then prepare few things""" if not self._enableModule(): raise GracefulTermination("Skipping FailoverRequest module") self.request.RequestName = "job_%d_request.xml" % self.jobID self.request.JobID = self.jobID self.request.SourceComponent = "Job_%d" % self.jobID def _execute(self): # report on the status of the input data, by default they are 'Processed', unless the job failed # failures happening before are not touched filesInFileReport = self.fileReport.getFiles() if not self._checkWFAndStepStatus(noPrint=True): for lfn in self.inputDataList: if lfn not in filesInFileReport: self.log.info("Forcing status to 'Unused' due to workflow failure for: %s" % (lfn)) # Set the force flag in case the file was in a terminal status self.fileReport.force = True self.fileReport.setFileStatus(int(self.production_id), lfn, TransformationFilesStatus.UNUSED) else: filesInFileReport = self.fileReport.getFiles() for lfn in self.inputDataList: if lfn not in filesInFileReport: self.log.verbose("No status populated for input data %s, setting to 'Processed'" % lfn) self.fileReport.setFileStatus(int(self.production_id), lfn, TransformationFilesStatus.PROCESSED) result = self.fileReport.commit() if not result["OK"]: self.log.error("Failed to report file status to TransformationDB") self.log.error("Trying again before populating request with file report information") result = self.fileReport.generateForwardDISET() if not result["OK"]: self.log.warn("Could not generate Operation for file report with result:\n%s" % (result["Value"])) else: if result["Value"] is None: self.log.info("Files correctly reported to TransformationDB") else: result = self.request.addOperation(result["Value"]) else: self.log.info("Status of files have been properly updated in the TransformationDB") # Must ensure that the local job report instance is used to report the final status # in case of failure and a subsequent failover operation if self.workflowStatus["OK"] and self.stepStatus["OK"]: self.setApplicationStatus("Job Finished Successfully") self.generateFailoverFile() def _finalize(self): """Finalize and report correct status for the workflow based on the workflow or step status. """ if not self._checkWFAndStepStatus(True): raise RuntimeError("Workflow failed, FailoverRequest module completed") super(FailoverRequest, self)._finalize("Workflow successful, end of FailoverRequest module execution.")