def _getReportInfos(self): result = [] defaultJob = Job() t_now = time.time() for jobNum in self._jobs: jobObj = self._jobDB.get(jobNum, defaultJob) runtime = parseStr(jobObj.get('runtime'), int, 0) for attempt in jobObj.history: if (attempt != jobObj.attempt) and not self._useHistory: continue if (attempt == jobObj.attempt) and (jobObj.state == Job.SUCCESS): time_info = runtime elif (attempt == jobObj.attempt - 1) and (jobObj.state != Job.SUCCESS): time_info = runtime elif attempt == jobObj.attempt: time_info = t_now - float(jobObj.submitted) else: time_info = 0 state = jobObj.state if attempt != jobObj.attempt: state = Job.FAILED dest = jobObj.history[attempt] if dest == 'N/A': dest_info = [dest] else: dest_info = dest.split('/') wmsName = jobObj.wmsId.split('.')[1] endpoint = 'N/A' if 'http:' in jobObj.wmsId: endpoint = jobObj.wmsId.split(':')[1].split('/')[0] result.append([state, time_info, wmsName, endpoint] + dest_info) return result
def _create_job_obj(self, name, data): try: job = Job() job.state = Job.str2enum(data.pop('status'), Job.UNKNOWN) if 'id' in data: gcID = data.pop('id') if not gcID.startswith('WMSID'): # Legacy support data['legacy_gcID'] = gcID if gcID.startswith('https'): gcID = 'WMSID.GLITEWMS.%s' % gcID else: wmsID, wmsName = tuple(gcID.split('.', 1)) gcID = 'WMSID.%s.%s' % (wmsName, wmsID) job.gcID = gcID for key in ['attempt', 'submitted', 'changed']: if key in data: setattr(job, key, data[key]) if 'runtime' not in data: if 'submitted' in data and (job.submitted > 0): data['runtime'] = time.time() - float(job.submitted) else: data['runtime'] = 0 for key in irange(1, job.attempt + 1): if ('history_' + str(key)).strip() in data: job.history[key] = data['history_' + str(key)] job.dict = data except Exception: raise JobError('Unable to parse data in %s:\n%r' % (name, data)) return job
def _getCategoryStateSummary(self): catStateDict = {} defaultJob = Job() for jobNum in self._jobs: jobState = self._jobDB.get(jobNum, defaultJob).state catKey = self._job2cat[jobNum] catStateDict[catKey][jobState] = catStateDict.setdefault( catKey, dict()).get(jobState, 0) + 1 return (catStateDict, dict(self._catDescDict), {} ) # (<state overview>, <descriptions>, <#subcategories>)
def reset(self, wms, select): jobs = self.jobDB.getJobs(JobSelector.create(select, task=self._task)) if jobs: self._log_user.warning('Resetting the following jobs:') self._reportClass(self.jobDB, self._task, jobs).display() if utils.getUserBool( 'Are you sure you want to reset the state of these jobs?', False): self.cancel( wms, self.jobDB.getJobs(ClassSelector(JobClass.PROCESSING), jobs), False, False) for jobNum in jobs: self.jobDB.commit(jobNum, Job())
def reset(self, task, wms, select): jobnum_list = self.job_db.get_job_list( JobSelector.create(select, task=task)) if jobnum_list: self._log.warning('Resetting the following jobs:') self._abort_report.show_report(self.job_db, jobnum_list) ask_user_msg = 'Are you sure you want to reset the state of these jobs?' if self._interactive_reset or self._uii.prompt_bool( ask_user_msg, False): self.cancel(wms, self.job_db.get_job_list( ClassSelector(JobClass.PROCESSING), jobnum_list), interactive=False, show_jobs=False) for jobnum in jobnum_list: self.job_db.commit(jobnum, Job())
def display(self): summary = lmap(lambda x: 0.0, Job.enumNames) defaultJob = Job() for jobNum in self._jobs: summary[self._jobDB.get(jobNum, defaultJob).state] += 1 makeSum = lambda *states: sum(imap(lambda z: summary[z], states)) makePer = lambda *states: [ makeSum(*states), round(makeSum(*states) / len(self._jobDB) * 100.0) ] # Print report summary self._printHeader('REPORT SUMMARY:') njobs_total = len(self._jobDB) jobov_succ = makePer(Job.SUCCESS) utils.vprint( 'Total number of jobs:%9d Successful jobs:%8d %3d%%' % tuple([njobs_total] + jobov_succ), -1) njobs_assigned = makeSum(Job.SUBMITTED, Job.WAITING, Job.READY, Job.QUEUED, Job.RUNNING) jobov_fail = makePer(Job.ABORTED, Job.CANCELLED, Job.FAILED) utils.vprint( 'Jobs assigned to WMS:%9d Failing jobs:%8d %3d%%' % tuple([njobs_assigned] + jobov_fail), -1) utils.vprint(' ' * 65 + '\nDetailed Status Information: ', -1, newline=False) ignored = len(self._jobDB) - sum(summary) if ignored: utils.vprint( '(Jobs IGNORED:%8d %3d%%)' % (ignored, ignored / len(self._jobDB) * 100.0), -1) else: utils.vprint(' ' * 31, -1) for stateNum, category in enumerate(Job.enumNames): utils.vprint('Jobs %9s:%8d %3d%% ' % tuple([category] + makePer(stateNum)), -1, newline=stateNum % 2) utils.vprint('-' * 65, -1) return 0
def _getSubmissionJobs(self, maxsample): # Get list of submittable jobs readyList = self.jobDB.getJobs(ClassSelector(JobClass.READY)) retryOK = readyList defaultJob = Job() if self._job_retries >= 0: retryOK = lfilter( lambda x: self.jobDB.get(x, defaultJob).attempt - 1 < self. _job_retries, readyList) modOK = lfilter(self._task.canSubmit, readyList) jobList = set.intersection(set(retryOK), set(modOK)) if self._showBlocker and readyList and not jobList: # No submission but ready jobs err = [] err += utils.QM((len(retryOK) > 0) and (len(modOK) == 0), [], ['have hit their maximum number of retries']) err += utils.QM((len(retryOK) == 0) and (len(modOK) > 0), [], ['are vetoed by the task module']) self._log_user_time.warning( 'All remaining jobs %s!', str.join(utils.QM(retryOK or modOK, ' or ', ' and '), err)) self._showBlocker = not (len(readyList) > 0 and len(jobList) == 0) # Determine number of jobs to submit submit = len(jobList) if self._njobs_inqueue > 0: submit = min( submit, self._njobs_inqueue - self.jobDB.getJobsN(ClassSelector(JobClass.ATWMS))) if self._njobs_inflight > 0: submit = min( submit, self._njobs_inflight - self.jobDB.getJobsN(ClassSelector(JobClass.PROCESSING))) if self._chunks_enabled and (maxsample > 0): submit = min(submit, maxsample) submit = max(submit, 0) if self._do_shuffle: return self._sample(jobList, submit) return sorted(jobList)[:submit]
def getJobPersistent(self, jobNum): return self._jobMap.get(jobNum, Job())
def get_job_persistent(self, jobnum): return self._job_map.get(jobnum, Job())