refactored cluster related code (renamed Job as Task and Job2 as Job to avoid confusion)
when Job2 was introduced, it was actually representing a job, but the class Job (which actually represented a Task, and this was misleading) already existed also: - added type hinting to ease code understanding - took this opportunity to fix styling issues
This commit is contained in:
parent
f36b2d9d9c
commit
6bf69f909b
|
@ -1,3 +1,6 @@
|
||||||
|
from typing import Optional, Dict, List
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
class JobStateFlags:
|
class JobStateFlags:
|
||||||
RUNNING = 1 # the job is running
|
RUNNING = 1 # the job is running
|
||||||
|
@ -14,133 +17,161 @@ class ParallelEnvironment:
|
||||||
MPI = 1
|
MPI = 1
|
||||||
|
|
||||||
|
|
||||||
|
MemoryUnit = int # number of bytes
|
||||||
|
JobState = int # combination of JobStateFlags
|
||||||
|
JobId = int # the job id in the sense of sge's job id : a simple unique number
|
||||||
|
TaskId = int # the id of a task within its array Job
|
||||||
|
QueueId = str # eg 'main.q'
|
||||||
|
QueueMachineId = str # the identifier of a queue machine, eg 'main.q@physix99.ipr.univ-rennes.fr'
|
||||||
|
ResourceRequest = str # eg 'mem_available=5G'
|
||||||
|
|
||||||
|
|
||||||
class JobRequirements:
|
class JobRequirements:
|
||||||
|
num_slots: Optional[int]
|
||||||
|
architecture: Optional[str] # machine architecture
|
||||||
|
m_parallelEnvironment: Optional[int] # todo: make ParallelEnvironment an Enum
|
||||||
|
queues: Optional[List[QueueId]] # the list of queues this job is allowed to run on
|
||||||
|
resources: Optional[List[ResourceRequest]]
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.m_numSlots = None
|
self.num_slots = None
|
||||||
self.m_strArchitecture = None # machine architecture
|
self.architecture = None
|
||||||
self.m_parallelEnvironment = None
|
self.m_parallelEnvironment = None
|
||||||
self.m_queues = None # the list of queues this job is allowed to run on
|
self.queues = None
|
||||||
|
self.resources = None
|
||||||
|
|
||||||
|
|
||||||
class JobId:
|
class TaskUid:
|
||||||
"""
|
"""
|
||||||
the identifier of a job.
|
the identifier of a task, in the form <job_id>.<element_id>
|
||||||
We treat each element of a job array as a separate job
|
We treat each element of a job array as a separate task
|
||||||
A single integer is no longer enough to identify a job because all elements in a job array
|
A single integer is no longer enough to identify a job because all elements in a job array
|
||||||
share the same sge job identifier. To uniquely define a job array element, we also use the task id.
|
share the same sge job identifier. To uniquely define a job array element, we also use the task id.
|
||||||
"""
|
"""
|
||||||
|
job_id: JobId
|
||||||
|
task_id: Optional[TaskId] # the identifier of a task within its job None if this identifier does not refer to a job array element
|
||||||
MAX_NUM_JOBS_IN_ARRAY = 1000000
|
MAX_NUM_JOBS_IN_ARRAY = 1000000
|
||||||
|
|
||||||
def __init__(self, iJobId, iJobArrayElementId=None):
|
def __init__(self, job_id: JobId, task_id: Optional[TaskId] = None):
|
||||||
if iJobArrayElementId is not None:
|
if task_id is not None:
|
||||||
assert iJobArrayElementId <= self.MAX_NUM_JOBS_IN_ARRAY
|
assert task_id <= self.MAX_NUM_JOBS_IN_ARRAY
|
||||||
self.m_iJobId = iJobId
|
self.job_id = job_id
|
||||||
self.m_iJobArrayElementId = iJobArrayElementId # None if this identifier does not refer to a job array element
|
self.task_id = task_id
|
||||||
|
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
"""
|
"""
|
||||||
required to use a JobId as a dict hash key
|
required to use a TaskUid as a dict hash key
|
||||||
"""
|
"""
|
||||||
hash = self.m_iJobId * self.MAX_NUM_JOBS_IN_ARRAY
|
hash = self.job_id * self.MAX_NUM_JOBS_IN_ARRAY
|
||||||
if self.m_iJobArrayElementId is not None:
|
if self.task_id is not None:
|
||||||
hash += self.m_iJobArrayElementId
|
hash += self.task_id
|
||||||
return hash
|
return hash
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other: 'TaskUid'):
|
||||||
"""
|
"""
|
||||||
required to use a JobId as a dict hash key
|
required to use a TaskUid as a dict hash key
|
||||||
"""
|
"""
|
||||||
if self.m_iJobId != other.m_iJobId:
|
if self.job_id != other.job_id:
|
||||||
return False
|
return False
|
||||||
if self.m_iJobArrayElementId != other.m_iJobArrayElementId:
|
if self.task_id != other.task_id:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def isJobArrayElement(self):
|
def is_job_array_element(self) -> bool:
|
||||||
return (self.m_iJobArrayElementId is not None)
|
return (self.task_id is not None)
|
||||||
|
|
||||||
def getMainId(self):
|
def get_job_id(self) -> JobId:
|
||||||
return self.m_iJobId
|
return self.job_id
|
||||||
|
|
||||||
def asStr(self):
|
def as_str(self):
|
||||||
strResult = '%s' % self.m_iJobId
|
result = '%s' % self.job_id
|
||||||
if self.isJobArrayElement():
|
if self.is_job_array_element():
|
||||||
strResult += '.%d' % self.m_iJobArrayElementId
|
result += '.%d' % self.task_id
|
||||||
return strResult
|
return result
|
||||||
|
|
||||||
|
|
||||||
class Job:
|
class Task:
|
||||||
def __init__(self, jobId):
|
task_uid: TaskUid # the unique identified of this task, eg '12345.789'
|
||||||
self.m_jobId = jobId
|
start_time: Optional[datetime]
|
||||||
self.m_startTime = None
|
submit_time: Optional[datetime]
|
||||||
self.m_submitTime = None
|
owner: Optional[str]
|
||||||
self.m_owner = None
|
script_name: Optional[str]
|
||||||
self.m_scriptName = None
|
slots: Dict[QueueMachineId, int]
|
||||||
self.m_slots = {}
|
state_flags: JobStateFlags
|
||||||
self.m_stateFlags = 0
|
job_requirements: JobRequirements
|
||||||
self.m_jobRequirements = JobRequirements()
|
requested_ram_per_core: MemoryUnit
|
||||||
self.m_requestedRamPerCore = 0
|
|
||||||
|
|
||||||
def getId(self):
|
def __init__(self, task_uid):
|
||||||
return self.m_jobId
|
self.task_uid = task_uid
|
||||||
|
self.start_time = None
|
||||||
|
self.submit_time = None
|
||||||
|
self.owner = None
|
||||||
|
self.script_name = None
|
||||||
|
self.slots = {}
|
||||||
|
self.state_flags = 0
|
||||||
|
self.job_requirements = JobRequirements()
|
||||||
|
self.requested_ram_per_core = 0
|
||||||
|
|
||||||
def setState(self, state):
|
def get_id(self):
|
||||||
self.m_stateFlags = state
|
return self.task_uid
|
||||||
|
|
||||||
def setOwner(self, jobOwner):
|
def set_state(self, state: JobState):
|
||||||
if self.m_owner:
|
self.state_flags = state
|
||||||
assert self.m_owner == jobOwner
|
|
||||||
self.m_owner = jobOwner
|
|
||||||
|
|
||||||
def getOwner(self):
|
def set_owner(self, job_owner: str):
|
||||||
return self.m_owner
|
if self.owner:
|
||||||
|
assert self.owner == job_owner
|
||||||
|
self.owner = job_owner
|
||||||
|
|
||||||
def setStartTime(self, jobStartTime):
|
def get_owner(self) -> str:
|
||||||
if self.m_startTime:
|
return self.owner
|
||||||
assert self.m_startTime == jobStartTime
|
|
||||||
self.m_startTime = jobStartTime
|
|
||||||
|
|
||||||
def setSubmitTime(self, jobSubmitTime):
|
def set_start_time(self, job_start_time: datetime):
|
||||||
if self.m_submitTime:
|
if self.start_time:
|
||||||
assert self.m_submitTime == jobSubmitTime
|
assert self.start_time == job_start_time
|
||||||
self.m_submitTime = jobSubmitTime
|
self.start_time = job_start_time
|
||||||
|
|
||||||
def getStartTime(self):
|
def get_submit_time(self, job_submit_time: datetime):
|
||||||
return self.m_startTime
|
if self.submit_time:
|
||||||
|
assert self.submit_time == job_submit_time
|
||||||
|
self.submit_time = job_submit_time
|
||||||
|
|
||||||
def setScriptName(self, jobScriptName):
|
def get_start_time(self) -> datetime:
|
||||||
if self.m_scriptName:
|
return self.start_time
|
||||||
assert self.m_scriptName == jobScriptName
|
|
||||||
self.m_scriptName = jobScriptName
|
|
||||||
|
|
||||||
def addSlots(self, queueMachineName, numSlots):
|
def set_script_name(self, job_script_name: str):
|
||||||
assert self.m_slots.get(queueMachineName) is None
|
if self.script_name:
|
||||||
if self.m_slots.get(queueMachineName) is None:
|
assert self.script_name == job_script_name
|
||||||
self.m_slots[queueMachineName] = numSlots
|
self.script_name = job_script_name
|
||||||
|
|
||||||
|
def add_slots(self, queue_machine_id: QueueMachineId, num_slots: int):
|
||||||
|
assert self.slots.get(queue_machine_id) is None
|
||||||
|
if self.slots.get(queue_machine_id) is None:
|
||||||
|
self.slots[queue_machine_id] = num_slots
|
||||||
else:
|
else:
|
||||||
# should never happen
|
# should never happen
|
||||||
self.m_slots[queueMachineName] += numSlots
|
self.slots[queue_machine_id] += num_slots
|
||||||
|
|
||||||
def getSlots(self):
|
def get_slots(self) -> Dict[QueueMachineId, int]:
|
||||||
return self.m_slots
|
return self.slots
|
||||||
|
|
||||||
def setNumRequiredSlots(self, numSlots):
|
def set_num_required_slots(self, num_slots: int):
|
||||||
self.m_jobRequirements.m_numSlots = numSlots
|
self.job_requirements.num_slots = num_slots
|
||||||
|
|
||||||
def isPending(self):
|
def is_pending(self):
|
||||||
"""
|
"""
|
||||||
returns true if this job is waiting in the queue for whatever reason
|
returns true if this task is waiting in the queue for whatever reason
|
||||||
"""
|
"""
|
||||||
return self.m_stateFlags & JobStateFlags.QUEUED
|
return self.state_flags & JobStateFlags.QUEUED
|
||||||
|
|
||||||
def getRequestedRamPerCore(self):
|
def get_requested_ram_per_core(self) -> MemoryUnit:
|
||||||
"""
|
"""
|
||||||
requested RAM per core in bytes
|
requested RAM per core in bytes
|
||||||
"""
|
"""
|
||||||
return self.m_requestedRamPerCore
|
return self.requested_ram_per_core
|
||||||
|
|
||||||
def setRequestedRamPerCore(self, requestedRam):
|
def set_requested_ram_per_core(self, requested_ram: MemoryUnit):
|
||||||
"""
|
"""
|
||||||
requestedRam : requested RAM per core in bytes
|
requestedRam : requested RAM per core in bytes
|
||||||
"""
|
"""
|
||||||
self.m_requestedRamPerCore = requestedRam
|
self.requested_ram_per_core = requested_ram
|
||||||
|
|
|
@ -1,35 +1,40 @@
|
||||||
|
from typing import Dict
|
||||||
from .Log import *
|
from .Log import *
|
||||||
|
from .Job import Task, TaskUid
|
||||||
|
|
||||||
|
|
||||||
class JobsState:
|
class JobsState:
|
||||||
"""
|
"""
|
||||||
represents a snapshot of the state of SGE jobs as seen by the SGE command "qstat -f -u \*"
|
represents a snapshot of the state of SGE jobs as seen by the SGE command "qstat -f -u \*"
|
||||||
"""
|
"""
|
||||||
|
tasks: Dict[TaskUid, Task]
|
||||||
|
job_array_tasks: Dict[int, Dict[TaskUid, Task]]
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.m_jobs = {} # list of jobs
|
self.tasks = {} # list of jobs
|
||||||
self.m_jobArrayJobs = {} # a dictionary of jobs for each job array, indexed by job array id
|
self.job_array_tasks = {} # a dictionary of jobs for each job array, indexed by job array id
|
||||||
self.m_queueMachines = {} # list of queue machines such as allintel.q@simpatix10
|
self.m_queueMachines = {} # list of queue machines such as allintel.q@simpatix10
|
||||||
self.m_stateTime = None # the time at which the state was snapshot
|
self.m_stateTime = None # the time at which the state was snapshot
|
||||||
|
|
||||||
def deleteAllJobs(self):
|
def deleteAllJobs(self):
|
||||||
self.m_jobs = {}
|
self.tasks = {}
|
||||||
self.m_jobArrayJobs = {}
|
self.job_array_tasks = {}
|
||||||
|
|
||||||
def addJob(self, job):
|
def addTask(self, task: Task):
|
||||||
jobId = job.getId()
|
task_uid = task.get_id()
|
||||||
self.m_jobs[jobId] = job
|
self.tasks[task_uid] = task
|
||||||
if jobId.isJobArrayElement():
|
if task_uid.is_job_array_element():
|
||||||
tasks = self.m_jobArrayJobs.get(jobId.m_iJobId)
|
tasks = self.job_array_tasks.get(task_uid.job_id)
|
||||||
if tasks is None:
|
if tasks is None:
|
||||||
tasks = {}
|
tasks = {}
|
||||||
self.m_jobArrayJobs[jobId.m_iJobId] = tasks
|
self.job_array_tasks[task_uid.job_id] = tasks
|
||||||
tasks[jobId] = job
|
tasks[task_uid] = task
|
||||||
|
|
||||||
def getJob(self, jobId):
|
def get_task(self, task_uid: TaskUid) -> Task:
|
||||||
return self.m_jobs.get(jobId)
|
return self.tasks.get(task_uid)
|
||||||
|
|
||||||
def getJobArrayJobs(self, iJobArrayId):
|
def get_job_array_tasks(self, job_array_id: int) -> Dict[TaskUid, Task]:
|
||||||
return self.m_jobArrayJobs.get(iJobArrayId)
|
return self.job_array_tasks.get(job_array_id)
|
||||||
|
|
||||||
def setTime(self, stateTime):
|
def setTime(self, stateTime):
|
||||||
self.m_stateTime = stateTime
|
self.m_stateTime = stateTime
|
||||||
|
@ -38,19 +43,19 @@ class JobsState:
|
||||||
return self.m_stateTime
|
return self.m_stateTime
|
||||||
|
|
||||||
def getJobsOnMachine(self, machineName):
|
def getJobsOnMachine(self, machineName):
|
||||||
jobsOnMachine = {}
|
jobs_on_machine = {}
|
||||||
for jobId, job in self.m_jobs.items():
|
for task_uid, task in self.tasks.items():
|
||||||
for queueMachineName, numSlots in job.getSlots().items():
|
for queueMachineName, numSlots in task.get_slots().items():
|
||||||
jobMachineName = queueMachineName.split('@')[1]
|
jobMachineName = queueMachineName.split('@')[1]
|
||||||
if jobMachineName == machineName:
|
if jobMachineName == machineName:
|
||||||
jobsOnMachine[jobId] = job
|
jobs_on_machine[task_uid] = task
|
||||||
return jobsOnMachine
|
return jobs_on_machine
|
||||||
|
|
||||||
def getNumFreeSlotsOnQueueMachine(self, queueMachine):
|
def getNumFreeSlotsOnQueueMachine(self, queueMachine):
|
||||||
# logInfo('getNumFreeSlotsOnQueueMachine : looking for free slots on queuemachine %s' % queueMachine.getName())
|
# logInfo('getNumFreeSlotsOnQueueMachine : looking for free slots on queuemachine %s' % queueMachine.getName())
|
||||||
numUsedSlots = 0
|
numUsedSlots = 0
|
||||||
for job in self.m_jobs.values():
|
for job in self.tasks.values():
|
||||||
numUsedSlotsByThisJob = job.getSlots().get(queueMachine.getName())
|
numUsedSlotsByThisJob = job.get_slots().get(queueMachine.getName())
|
||||||
if numUsedSlotsByThisJob is not None:
|
if numUsedSlotsByThisJob is not None:
|
||||||
# logInfo('getNumFreeSlotsOnQueueMachine : job %d uses %d slots' % (job.getId().asStr(), numUsedSlotsByThisJob))
|
# logInfo('getNumFreeSlotsOnQueueMachine : job %d uses %d slots' % (job.getId().asStr(), numUsedSlotsByThisJob))
|
||||||
numUsedSlots += numUsedSlotsByThisJob
|
numUsedSlots += numUsedSlotsByThisJob
|
||||||
|
@ -80,7 +85,7 @@ class JobsState:
|
||||||
|
|
||||||
def getPendingJobs(self):
|
def getPendingJobs(self):
|
||||||
pendingJobs = {}
|
pendingJobs = {}
|
||||||
for jobId, job in self.m_jobs.items():
|
for jobId, job in self.tasks.items():
|
||||||
if job.isPending():
|
if job.is_pending():
|
||||||
pendingJobs[job.getId()] = job
|
pendingJobs[job.get_id()] = job
|
||||||
return pendingJobs
|
return pendingJobs
|
||||||
|
|
|
@ -4,35 +4,35 @@ from .JobsState import JobsState
|
||||||
from .QueueMachine import QueueMachine, QueueMachineStateFlags
|
from .QueueMachine import QueueMachine, QueueMachineStateFlags
|
||||||
from .Util import *
|
from .Util import *
|
||||||
from .Log import logError
|
from .Log import logError
|
||||||
from .Job import JobStateFlags, JobId, Job, ParallelEnvironment
|
from .Job import JobStateFlags, TaskUid, Task, ParallelEnvironment, JobState
|
||||||
import logging
|
import logging
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
|
||||||
class QstatParser:
|
class QstatParser:
|
||||||
def parseJobState(self, strJobStatus):
|
def parseJobState(self, job_status_as_str: str) -> JobState:
|
||||||
jobState = 0
|
job_state = 0
|
||||||
for i in range(0, len(strJobStatus)):
|
for i in range(0, len(job_status_as_str)):
|
||||||
c = strJobStatus[i]
|
c = job_status_as_str[i]
|
||||||
if c == 'r':
|
if c == 'r':
|
||||||
jobState += JobStateFlags.RUNNING
|
job_state += JobStateFlags.RUNNING
|
||||||
elif c == 'w':
|
elif c == 'w':
|
||||||
jobState += JobStateFlags.WAITING
|
job_state += JobStateFlags.WAITING
|
||||||
elif c == 'q':
|
elif c == 'q':
|
||||||
jobState += JobStateFlags.QUEUED
|
job_state += JobStateFlags.QUEUED
|
||||||
elif c == 't':
|
elif c == 't':
|
||||||
jobState += JobStateFlags.TRANSFERING
|
job_state += JobStateFlags.TRANSFERING
|
||||||
elif c == 'd':
|
elif c == 'd':
|
||||||
jobState += JobStateFlags.DELETED
|
job_state += JobStateFlags.DELETED
|
||||||
elif c == 'h':
|
elif c == 'h':
|
||||||
jobState += JobStateFlags.HOLD
|
job_state += JobStateFlags.HOLD
|
||||||
elif c == 's':
|
elif c == 's':
|
||||||
jobState += JobStateFlags.SUSPENDED
|
job_state += JobStateFlags.SUSPENDED
|
||||||
elif c == 'E':
|
elif c == 'E':
|
||||||
jobState += JobStateFlags.ERROR
|
job_state += JobStateFlags.ERROR
|
||||||
else:
|
else:
|
||||||
assert False, 'unhandled job state flag :"' + c + '"'
|
assert False, 'unhandled job state flag :"' + c + '"'
|
||||||
return jobState
|
return job_state
|
||||||
|
|
||||||
def parseQueueMachineState(self, strQueueMachineStatus):
|
def parseQueueMachineState(self, strQueueMachineStatus):
|
||||||
queueMachineState = 0
|
queueMachineState = 0
|
||||||
|
@ -134,8 +134,8 @@ class QstatParser:
|
||||||
if not bInPendingJobsSection:
|
if not bInPendingJobsSection:
|
||||||
assert currentQueueMachine
|
assert currentQueueMachine
|
||||||
# log('QstatParser::parseQstatOutput : jobId = "'+matchObj.group('jobId')+'"')
|
# log('QstatParser::parseQstatOutput : jobId = "'+matchObj.group('jobId')+'"')
|
||||||
iJobId = int(matchObj.group('jobId'))
|
job_id = int(matchObj.group('jobId'))
|
||||||
logging.debug('iJobId = %d' % iJobId)
|
logging.debug('iJobId = %d' % job_id)
|
||||||
jobState = self.parseJobState(matchObj.group('jobStatus'))
|
jobState = self.parseJobState(matchObj.group('jobStatus'))
|
||||||
strJobArrayDetails = matchObj.group('jobArrayDetails')
|
strJobArrayDetails = matchObj.group('jobArrayDetails')
|
||||||
bIsJobArray = (len(strJobArrayDetails) != 0)
|
bIsJobArray = (len(strJobArrayDetails) != 0)
|
||||||
|
@ -154,33 +154,33 @@ class QstatParser:
|
||||||
logging.debug('task_ids = %s' % task_ids)
|
logging.debug('task_ids = %s' % task_ids)
|
||||||
for task_id in task_ids:
|
for task_id in task_ids:
|
||||||
logging.debug('task_id = %s' % task_id)
|
logging.debug('task_id = %s' % task_id)
|
||||||
jobId = None
|
task_uid = None
|
||||||
if bIsJobArray:
|
if bIsJobArray:
|
||||||
jobId = JobId(iJobId, task_id)
|
task_uid = TaskUid(job_id, task_id)
|
||||||
else:
|
else:
|
||||||
jobId = JobId(iJobId)
|
task_uid = TaskUid(job_id)
|
||||||
job = jobsState.getJob(jobId)
|
task = jobsState.get_task(task_uid)
|
||||||
# logDebug('iElementIndex = %d job id = %s' % (iElementIndex, jobId.asStr()))
|
# logDebug('iElementIndex = %d job id = %s' % (iElementIndex, jobId.asStr()))
|
||||||
if job is None:
|
if task is None:
|
||||||
# this job hasn't been encountered yet in the output of qstat ...
|
# this job hasn't been encountered yet in the output of qstat ...
|
||||||
# we could either be in the pending jobs section or in the running jobs section
|
# we could either be in the pending jobs section or in the running jobs section
|
||||||
job = Job(jobId)
|
task = Task(task_uid)
|
||||||
jobsState.addJob(job)
|
jobsState.addTask(task)
|
||||||
job.setState(jobState)
|
task.set_state(jobState)
|
||||||
strJobStartOrSubmitTime = matchObj.group('jobStartOrSubmitTime')
|
strJobStartOrSubmitTime = matchObj.group('jobStartOrSubmitTime')
|
||||||
jobStartOrSubmitTime = time.strptime(strJobStartOrSubmitTime, '%m/%d/%Y %H:%M:%S')
|
jobStartOrSubmitTime = time.strptime(strJobStartOrSubmitTime, '%m/%d/%Y %H:%M:%S')
|
||||||
if bInPendingJobsSection:
|
if bInPendingJobsSection:
|
||||||
job.setSubmitTime(jobStartOrSubmitTime)
|
task.get_submit_time(jobStartOrSubmitTime)
|
||||||
else:
|
else:
|
||||||
job.setStartTime(jobStartOrSubmitTime)
|
task.set_start_time(jobStartOrSubmitTime)
|
||||||
job.setOwner(matchObj.group('jobOwner'))
|
task.set_owner(matchObj.group('jobOwner'))
|
||||||
job.setScriptName(matchObj.group('jobScriptName'))
|
task.set_script_name(matchObj.group('jobScriptName'))
|
||||||
if bInPendingJobsSection:
|
if bInPendingJobsSection:
|
||||||
job.setNumRequiredSlots(int(matchObj.group('numSlots')))
|
task.set_num_required_slots(int(matchObj.group('numSlots')))
|
||||||
else:
|
else:
|
||||||
assert not bInPendingJobsSection # if we are in the pending jobs section, the job should be new
|
assert not bInPendingJobsSection # if we are in the pending jobs section, the job should be new
|
||||||
if not bInPendingJobsSection:
|
if not bInPendingJobsSection:
|
||||||
job.addSlots(currentQueueMachine.getName(), int(matchObj.group('numSlots')))
|
task.add_slots(currentQueueMachine.getName(), int(matchObj.group('numSlots')))
|
||||||
else:
|
else:
|
||||||
# the current line does not describe a job
|
# the current line does not describe a job
|
||||||
if not bInPendingJobsSection:
|
if not bInPendingJobsSection:
|
||||||
|
|
Loading…
Reference in New Issue