From simon.urbanek at r-project.org  Thu May 16 20:56:45 2013
From: simon.urbanek at r-project.org (Simon Urbanek)
Date: Thu, 16 May 2013 14:56:45 -0400
Subject: [Rd] setTimeLimit sometimes fails to terminate idle call in R
In-Reply-To: <CABFfbXsBsTt4aHvTePo+0iCnkQ3df+RwcpwogXH40RmtB=BYiA@mail.gmail.com>
References: <CABFfbXsBsTt4aHvTePo+0iCnkQ3df+RwcpwogXH40RmtB=BYiA@mail.gmail.com>
Message-ID: <9187D1C3-2FDD-4432-9FCE-FB4CEDC53A92@r-project.org>

Jeroen,

On May 16, 2013, at 2:12 PM, Jeroen Ooms wrote:

> I would like to use setTimeLimit to abort operations that are stuck
> waiting (idle) after n seconds. Below a toy example in which Sys.sleep
> is a placeholder call that is idle:
> 
> testlimit <- function(){
>  setTimeLimit(elapsed=3, transient=TRUE);
>  Sys.sleep(10);
> }
> system.time(testlimit());
> 
> However this is giving inconsistent results. On windows and in
> r-studio server (linux) the call is correctly aborted after 3 seconds.
> However, when I run this in a terminal session in either on linux or
> osx, the timeout is not triggered until after Sys.sleep() returns and
> the total script takes 10+ seconds to complete.
> 
> What causes this difference?

The time limit can only be checked in R_ProcessEvents() so for all practical purposes it can be only triggered by interruptible code that calls R_CheckUserInterrupt().
Now, it is entirely up to the front-end to decide how it will the the event loop. For example the terminal version of R has no other interrupts to worry about other than input handlers which trigger asynchronously, so it doesn't need to do any polling. Sys.sleep() only triggers on input handlers, so if you don't have any external event source hook as input handler, there is no reason to process any events so Sys.sleep() won't see any reason to check the time limit.


> Is there something I can set in my terminal R session such that the time limit is triggered?

On OS X it's actually very easy:

quartz(); dev.off()

will do the trick. The reason is that Quartz needs to force the event loop in order to process events from the window asynchronously. It does so by installing a timer-based input handler. This handler will make sure that Sys.sleep() will wake up every 100ms (you can change the value using QuartzCocoa_SetLatency) so it will timeout with that resolution:

> testlimit <- function(){
+  setTimeLimit(elapsed=3, transient=TRUE);
+  Sys.sleep(10);
+ }
> system.time(testlimit());
Error in Sys.sleep(10) : reached elapsed time limit
Timing stopped at: 0 0.001 10.001 
> quartz(); dev.off()
null device 
          1 
> testlimit <- function(){
+  setTimeLimit(elapsed=3, transient=TRUE);
+  Sys.sleep(10);
+ }
> system.time(testlimit());
Error in Sys.sleep(10) : reached elapsed time limit
Timing stopped at: 0.002 0.003 3.019 


On Linux, there is no built-in timer, so you'd have to add an input handler that will pre-empt Sys.sleep(). If you want a constant timer, you can simply borrow the code from Quartz (have a look at QuartzCocoa_SetupEventLoop in src/library/grDevices/src/qdCocoa.m) or the CarbonEL package. It's really just a pipe that is added as an input handler into which you write asynchronously when you want to wake up the event loop. On top of my head I can't think of a built-in solution in R at this point (even though it could be argued that R might install a handler itself when the limit is set ...).

But note that this is really just a special case of of Sys.sleep(). If you actually run R code, then ProcessEvents is triggered automatically during the evaluation (or in interruptible C code).

Cheers,
Simon


> I am using
> Ubuntu 13.04 (x64), and osx 10.8. Below three videos to illustrate the
> issue:
> 
>  [1]: http://www.youtube.com/watch?v=d1qxbp2W2mY&hd=1
>  [2]: http://www.youtube.com/watch?v=S0r-O9er4kU&hd=1
>  [3]: http://www.youtube.com/watch?v=2D7TgtXUa3o&hd=1
> 
>> sessionInfo()
> R version 3.0.1 RC (2013-05-10 r62729)
> Platform: x86_64-pc-linux-gnu (64-bit)
> 
> locale:
> [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C
> [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8
> [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8
> [7] LC_PAPER=C                 LC_NAME=C
> [9] LC_ADDRESS=C               LC_TELEPHONE=C
> [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
> 
> attached base packages:
> [1] stats     graphics  grDevices utils     datasets  methods   base
> 
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
> 
> 



[Rd] setTimeLimit sometimes fails to terminate idle call in R
Simon Urbanek