Emman
Emman

Reputation: 4201

How to re-run a piece of code if it hangs for more than x seconds?

I have a piece of code whose execution time varies. Some time it takes 5 seconds, other times it could take much longer. I want to put a time limit such that if execution time hangs for more than 5 seconds, then interrupt and re-run the code (and hopefully it would run more quickly (i.e., <= 5 seconds).

I found that R.utils::withTimeout() is good for this task. However, I'm not sure how to create the rerunning loop. Consider the following piece of code for example. square_slowly() is a function that squares a number, with varying execution times. It could take any time between 1 to 10 seconds to run.

square_slowly <- function(x) {
  idle_time <- sample(1:10, 1)
  Sys.sleep(idle_time)
  
  message(paste0("it took ", idle_time, " seconds"))
  return(x * x)
}

set.seed(100)

square_slowly(3)
#> it took 10 seconds
#> [1] 9

So I want to monitor square_slowly(): if it takes more than 5 seconds, then rerun. Repeat re-running until it runs in 5 seconds or faster.

I assume I need a repeat() loop, but not sure how to do it.


EDIT


Ideally, I would like to add a message in case such a re-run happens. That is, for every re-run, print a message such as more than 5 seconds have elapsed; re-running.

Upvotes: 2

Views: 433

Answers (1)

Waldi
Waldi

Reputation: 41230

One possible implementation:

run <- function(x,timeout) {
res <- tryCatch(R.utils::withTimeout(square_slowly(x),timeout=timeout),error=function(cond) NULL)
if (is.null(res)) res <- Recall(x,timeout)
return(res)
}

run(3,timeout = 5)
it took 4 seconds
[1] 9

Or in functional form:

run <- function(.f,...,timeout,trial=1) {
  cat('run',trial,'\n')
  res <- tryCatch(R.utils::withTimeout(do.call(.f,list(...)),timeout=timeout),error=function(cond) NULL)
  if (is.null(res)) res <- Recall(.f=.f,unlist(list(...)),timeout=timeout,trial = trial + 1)
  return(res)
}
run(square_slowly,3,timeout = 5)

run 1 
run 2 
run 3 
run 4 
run 5 
run 6 
it took 4 seconds
[1] 9


Upvotes: 4

Related Questions