Carl Witthoft
Carl Witthoft

Reputation: 21532

setTimeLimit persists after function completes

Using a simple test function

timefoo<-function(x,trans=TRUE){
setTimeLimit(elapse=4, transient=trans)
warning('starting...')
Sys.sleep(x)
warning('woke up')
return(x)
}

The function terminates properly when I call, say, timefoo(5) , but:

 timefoo(3)
[1] 3
Warning messages:
1: In timefoo(3) : starting...
2: In timefoo(3) : woke up
Error: reached elapsed time limit

Can someone explain what exactly is happening? It's as though setTimeLimit keeps running after timefoo has finished and exited. Setting transient=FALSE is worse, as it then sets the timeout for my console commands and gives me the error message after every command (plus 4 seconds).

Edit: in response to Gavin's questions, here's a sequence of two calls

Rgames> timefoo(5)
Error in Sys.sleep(x) : reached elapsed time limit
In addition: Warning message:
In timefoo(5) : starting...
Rgames> timefoo(3)
[1] 3
Warning messages:
1: In timefoo(3) : starting...
2: In timefoo(3) : woke up
Error: reached elapsed time limit

I manually waited 10 sec between commands, so there's no doubt the final error message is due to the timefoo(3) call. Are there any R_ENVIRON variables that I may have fouled up that are causing this behavior? I've only tested this so far on Windows7, R64.

Upvotes: 4

Views: 2420

Answers (1)

Richie Cotton
Richie Cotton

Reputation: 121177

I get the same error message (running R-2.16 devel under Win 7).

The help page ?setTimeLimit states:

‘setTimeLimit’ sets limits which apply to each top-level computation, that is a command line (including any continuation lines) entered at the console or from a file.

So it isn't really designed to be run from inside a function. If you want to do that, then try this alternative:

timed_computation <- function(expr, time_limit = 1)
{
  setTimeLimit(elapsed = time_limit, transient = TRUE)
  ans <- expr
  setTimeLimit(elapsed = Inf, transient = TRUE)
  ans
}

timed_computation(1 + 1)            #should return 2
timed_computation(Sys.sleep(2))     #should throw an error

Upvotes: 4

Related Questions