Search code examples
rparallel-processingexit

How to run on.exit if user aborts/interrupts the calculation?


Question: In R or RStudio, if a user aborts an ongoing calculation (by clicking the stop sign or pressing esc), on.exit is not called. Is there a way such that if the user presses esc, a certain statement runs first before aborting the calculation?

Example:

testf <- function() {Sys.sleep(3); on.exit(cat("on.exit output"))}
testf()

When pressing esc, no output is printed.

Real world example: I am using cl <- parallel::makePSOCKcluster(2) within a function to use parLapply. When the user aborts the calculation, I want to call stopCluster(cl). I am on a MacBook m3, but this needs to work on Windows as well.


Solution

  • In your function par_fun, make cluster and define on.exit in subsequent lines.

    > par_fun <- \(ncpu=2L) {
    +   cl <- parallel::makePSOCKcluster(ncpu)
    +   on.exit(parallel::stopCluster(cl))
    +   parallel::parLapply(cl, seq_len(3), inner_fun)
    + }
    > par_fun()  ## normal run
    [[1]]
    [1] "Done."
    
    [[2]]
    [1] "Done."
    
    [[3]]
    [1] "Done."
    
    > showConnections()
         description class mode text isopen can read can write
    > par_fun()  ## interrupted
    > showConnections()
         description class mode text isopen can read can write
    

    Data:

    inner_fun <- \(i) {Sys.sleep(1); return('Done.')}