Signal handling in R
Recently I have been programming quite a lot in R, and today stumbled over the problem to implement a kind of monitoring loop in R. Typically that would be a infinite loop with sleep calls, but I wanted to allow for waking up from the sleep via sending UNIX style signals, in particular SIGINT. After some searching I found Beyond Exception Handling: Conditions and Restarts from the Advanced R book. But it didn’t really help me a lot to program an interrupt handler.
My requirements were:
- an interruption of the work-part should be immediately restarted
- an interruption of the sleep-part should go immediately into the work-part
Unfortunately it seems not to be possible to ignore interrupts at all from with the R code. The best one can do is install interrupt handlers and try to repeat the code which was executed while the interrupt happened. This is what I tried to implement with the following code below. I still have to digest the documentation about conditions and restarts, and play around a lot, but at least this is an initial working version.
workfun <- function() {
i <- 1
do_repeat <- FALSE
while (TRUE) {
message("begin of the loop")
withRestarts(
{
# do all the work here
cat("Entering work part i =", i, "\n");
Sys.sleep(10)
i <- i + 1
cat("finished work part\n")
},
gotSIG = function() {
message("interrupted while working, restarting work part")
do_repeat <<- TRUE
NULL
}
)
if (do_repeat) {
cat("restarting work loop\n")
do_repeat <- FALSE
next
} else {
cat("between work and sleep part\n")
}
withRestarts(
{
# do the sleep part here
cat("Entering sleep part i =", i, "\n")
Sys.sleep(10)
i <- i + 1
cat("finished sleep part\n")
},
gotSIG = function() {
message("got work to do, waking up!")
NULL
}
)
message("end of the loop")
}
}
cat("Current process:", Sys.getpid(), "\n");
withCallingHandlers({
workfun()
},
interrupt = function(e) {
invokeRestart("gotSIG")
})
While not perfect, I guess I have to live with this method for now.
1 Response
[…] Signal handling in R […]