Skip to content

Commit a23e350

Browse files
authored
Merge pull request #7328 from sfayer/cherry-pick-2-af3b2b349-integration
[sweep:integration] Improve performance of job delete/kill/reschedule API
2 parents c2c9477 + 6562a06 commit a23e350

File tree

2 files changed

+51
-19
lines changed

2 files changed

+51
-19
lines changed

src/DIRAC/Interfaces/API/Dirac.py

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1449,14 +1449,15 @@ def deleteJob(self, jobID):
14491449
return ret
14501450
jobIDs = ret["Value"]
14511451

1452-
jobIDsToDelete = []
1453-
for jobID in jobIDs:
1454-
can_kill = JobStatus.checkJobStateTransition(jobID, JobStatus.KILLED)["OK"]
1455-
can_del = JobStatus.checkJobStateTransition(jobID, JobStatus.DELETED)["OK"]
1456-
if can_kill or can_del:
1457-
jobIDsToDelete.append(jobID)
1452+
# Remove any job IDs that can't change to the Killed or Deleted states
1453+
filteredJobs = set()
1454+
for filterState in (JobStatus.KILLED, JobStatus.DELETED):
1455+
filterRes = JobStatus.filterJobStateTransition(jobIDs, filterState)
1456+
if not filterRes["OK"]:
1457+
return filterRes
1458+
filteredJobs.update(filterRes["Value"])
14581459

1459-
return WMSClient(useCertificates=self.useCertificates).deleteJob(jobIDsToDelete)
1460+
return WMSClient(useCertificates=self.useCertificates).deleteJob(list(filteredJobs))
14601461

14611462
#############################################################################
14621463

@@ -1481,11 +1482,11 @@ def rescheduleJob(self, jobID):
14811482
return ret
14821483
jobIDs = ret["Value"]
14831484

1484-
jobIDsToReschedule = []
1485-
for jobID in jobIDs:
1486-
res = JobStatus.checkJobStateTransition(jobID, JobStatus.RESCHEDULED)
1487-
if res["OK"]:
1488-
jobIDsToReschedule.append(jobID)
1485+
# Remove any job IDs that can't change to the rescheduled state
1486+
filterRes = JobStatus.filterJobStateTransition(jobIDs, JobStatus.RESCHEDULED)
1487+
if not filterRes["OK"]:
1488+
return filterRes
1489+
jobIDsToReschedule = filterRes["Value"]
14891490

14901491
return WMSClient(useCertificates=self.useCertificates).rescheduleJob(jobIDsToReschedule)
14911492

@@ -1508,14 +1509,15 @@ def killJob(self, jobID):
15081509
return ret
15091510
jobIDs = ret["Value"]
15101511

1511-
jobIDsToKill = []
1512-
for jobID in jobIDs:
1513-
can_kill = JobStatus.checkJobStateTransition(jobID, JobStatus.KILLED)["OK"]
1514-
can_del = JobStatus.checkJobStateTransition(jobID, JobStatus.DELETED)["OK"]
1515-
if can_kill or can_del:
1516-
jobIDsToKill.append(jobID)
1512+
# Remove any job IDs that can't change to the Killed or Deleted states
1513+
filteredJobs = set()
1514+
for filterState in (JobStatus.KILLED, JobStatus.DELETED):
1515+
filterRes = JobStatus.filterJobStateTransition(jobIDs, filterState)
1516+
if not filterRes["OK"]:
1517+
return filterRes
1518+
filteredJobs.update(filterRes["Value"])
15171519

1518-
return WMSClient(useCertificates=self.useCertificates).killJob(jobIDsToKill)
1520+
return WMSClient(useCertificates=self.useCertificates).killJob(list(filteredJobs))
15191521

15201522
#############################################################################
15211523

src/DIRAC/WorkloadManagementSystem/Client/JobStatus.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from DIRAC import gLogger, S_OK, S_ERROR
66
from DIRAC.Core.Utilities.StateMachine import State, StateMachine
7+
from DIRAC.Core.Utilities.Decorators import deprecated
78

89

910
#:
@@ -97,6 +98,7 @@ def __init__(self, state):
9798
}
9899

99100

101+
@deprecated("Use filterJobStateTransition instead")
100102
def checkJobStateTransition(jobID, candidateState, currentStatus=None, jobMonitoringClient=None):
101103
"""Utility to check if a job state transition is allowed"""
102104
if not currentStatus:
@@ -125,3 +127,31 @@ def checkJobStateTransition(jobID, candidateState, currentStatus=None, jobMonito
125127
)
126128
return S_ERROR("Job state transition not allowed")
127129
return S_OK()
130+
131+
132+
def filterJobStateTransition(jobIDs, candidateState, jobMonitoringClient=None):
133+
"""Given a list of jobIDs, return a list that are allowed to transition
134+
to the given candidate state.
135+
"""
136+
allowedJobs = []
137+
138+
if not isinstance(jobIDs, list):
139+
jobIDs = [jobIDs]
140+
141+
if not jobMonitoringClient:
142+
from DIRAC.WorkloadManagementSystem.Client.JobMonitoringClient import JobMonitoringClient
143+
144+
jobMonitoringClient = JobMonitoringClient()
145+
146+
res = jobMonitoringClient.getJobsStatus(jobIDs)
147+
if not res["OK"]:
148+
return res
149+
150+
for jobID in jobIDs:
151+
if jobID in res["Value"]:
152+
curState = res["Value"][jobID]["Status"]
153+
stateRes = JobsStateMachine(curState).getNextState(candidateState)
154+
if stateRes["OK"]:
155+
if stateRes["Value"] == candidateState:
156+
allowedJobs.append(jobID)
157+
return S_OK(allowedJobs)

0 commit comments

Comments
 (0)