@@ -151,3 +151,120 @@ slurm_version <- local({
151151 version
152152 }
153153})
154+
155+
156+ # Patch Slurm cluster functions listJobsQueued() and listJobsRunning()
157+ # to use `sacct` instead of `squeue`
158+ # ' @importFrom batchtools assertRegistry runOSCommand
159+ # ' @importFrom utils tail
160+ patchClusterFunctionsSlurm <- function (cf ) {
161+ OSError <- import_from(" OSError" , package = " batchtools" )
162+ stopifnot(inherits(cf , " ClusterFunctions" ))
163+
164+ env <- environment(cf [[" listJobsQueued" ]])
165+ array.jobs <- env [[" array.jobs" ]]
166+ getClusters <- env [[" getClusters" ]]
167+ nodename <- env [[" nodename" ]]
168+
169+ listJobs <- function (reg , args ) {
170+ assertRegistry(reg , writeable = FALSE )
171+ args <- c(args , " --user=$USER" , " --noheader" , " --parsable2" , " --allocations" , " --format=JobID" )
172+ clusters <- getClusters(reg )
173+ if (length(clusters ) > 0 ) {
174+ args <- c(args , sprintf(" --clusters=%s" , clusters ))
175+ }
176+ res <- runOSCommand(" sacct" , args , nodename = nodename )
177+ if (res $ exit.code > 0L ) {
178+ OSError(" Listing of jobs failed" , res )
179+ }
180+ if (length(clusters ) > 0 ) {
181+ res <- tail(res $ output , - 1L )
182+ } else {
183+ res <- res $ output
184+ }
185+ res
186+ } # # listJobs()
187+
188+ cf $ listJobsQueued <- function (reg ) {
189+ # # List PENDING (PD) and REQUEUED (RQ) jobs
190+ listJobs(reg , " --state=PD,RQ" )
191+ }
192+
193+ cf $ listJobsRunning <- function (reg ) {
194+ # # List RUNNING (R), SUSPENDED (S), RESIZING (RS) jobs
195+ listJobs(reg , " --state=R,S,RS" )
196+ }
197+
198+ cf
199+ } # # patchClusterFunctionsSlurm()
200+
201+
202+
203+ # Patch Slurm cluster functions listJobsQueued() and listJobsRunning()
204+ # to use `sacct` instead of `squeue`
205+ # ' @importFrom batchtools assertRegistry runOSCommand
206+ # ' @importFrom utils tail
207+ patchClusterFunctionsSlurm2 <- function (cf ) {
208+ OSError <- import_from(" OSError" , package = " batchtools" )
209+ stopifnot(inherits(cf , " ClusterFunctions" ))
210+
211+ env <- environment(cf [[" listJobsQueued" ]])
212+ array.jobs <- env [[" array.jobs" ]]
213+ getClusters <- env [[" getClusters" ]]
214+ nodename <- env [[" nodename" ]]
215+ org_listJobsQueued <- env [[" listJobsQueued" ]]
216+
217+ isJobQueued <- function (reg , batch_id ) {
218+ stopifnot(length(batch_id ) == 1L , ! is.na(batch_id ), nzchar(batch_id ))
219+
220+ # # FIXME: Add also --starttime=<start time>, because 'sacct' only returns jobs ran today
221+ args <- c(" --user=$USER" , " --noheader" , " --parsable2" , " --allocations" , " --format=State" , sprintf(" --jobs=%s" , batch_id ))
222+ clusters <- getClusters(reg )
223+ if (length(clusters ) > 0 ) {
224+ args <- c(args , sprintf(" --clusters=%s" , clusters ))
225+ }
226+ res <- runOSCommand(" sacct" , args , nodename = nodename )
227+ if (res $ exit.code > 0L ) {
228+ OSError(" Failed to check if job is pending" , res )
229+ }
230+ if (length(clusters ) > 0 ) {
231+ res <- tail(res $ output , - 1L )
232+ } else {
233+ res <- res $ output
234+ }
235+
236+ if (length(res ) == 0 ) return (FALSE )
237+
238+ res %in% c(" PENDING" , " REQUEUED" )
239+ } # # isJobQueued()
240+
241+ cf $ listJobsQueued <- function (reg ) {
242+ batch_id <- getOption(" future.batchtools.batch_id" , NULL )
243+
244+ # # Queued jobs according to 'squeue'
245+ jobs <- org_listJobsQueued(reg )
246+ if (is.null(batch_id )) return (jobs )
247+
248+ # # Is the job queued?
249+ if (length(jobs ) > 0 ) {
250+ jobs <- intersect(jobs , as.character(batch_id ))
251+ if (length(jobs ) > 0 ) return (jobs )
252+ }
253+
254+ # # Ask 'sacct' it if is PENDING or REQUEUED
255+ if (isJobQueued(reg , batch_id )) jobs <- as.character(batch_id )
256+
257+ jobs
258+ }
259+
260+ cf
261+ } # # patchClusterFunctionsSlurm2()
262+
263+
264+ # ' @importFrom batchtools makeClusterFunctionsSlurm
265+
266+ makeClusterFunctionsSlurm2 <- function (template = " slurm" , array.jobs = TRUE , nodename = " localhost" , scheduler.latency = 1 , fs.latency = 65 , ... ) {
267+ cf <- makeClusterFunctionsSlurm(template = template , array.jobs = array.jobs , nodename = nodename , scheduler.latency = scheduler.latency , fs.latency = fs.latency , ... )
268+ cf <- patchClusterFunctionsSlurm2(cf )
269+ cf
270+ }
0 commit comments