Timers in R Programming Language

We often want to execute code at some point in the future, or repeatedly at some interval. R’s built-in functions make both of these tasks easy. We’ll look at how to implement timers in R.

library(R6)

# Create a Timer class
Timer <- R6Class("Timer",
  public = list(
    duration = NULL,
    callback = NULL,
    timer_id = NULL,
    
    initialize = function(duration, callback) {
      self$duration <- duration
      self$callback <- callback
    },
    
    start = function() {
      self$timer_id <- later::later(self$callback, delay = self$duration)
    },
    
    stop = function() {
      if (!is.null(self$timer_id)) {
        later::cancel(self$timer_id)
        return(TRUE)
      }
      return(FALSE)
    }
  )
)

main <- function() {
  # Timer 1 will wait 2 seconds
  timer1 <- Timer$new(2, function() {
    cat("Timer 1 fired\n")
  })
  timer1$start()
  
  # We use Sys.sleep() to wait for the timer to fire
  Sys.sleep(2)
  
  # Timer 2 example with cancellation
  timer2 <- Timer$new(1, function() {
    cat("Timer 2 fired\n")
  })
  timer2$start()
  
  # Attempt to stop timer2
  stopped <- timer2$stop()
  if (stopped) {
    cat("Timer 2 stopped\n")
  }
  
  # Give timer2 enough time to fire, if it ever was going to
  Sys.sleep(2)
}

main()

In this R implementation:

  1. We use the R6 library to create a Timer class that mimics the behavior of Go’s timer.

  2. The Timer class has methods to start and stop the timer, using the later package for asynchronous execution.

  3. In the main function, we create two timers:

    • timer1 waits for 2 seconds and then prints a message.
    • timer2 is set to wait for 1 second, but we attempt to stop it before it fires.
  4. We use Sys.sleep() to pause the execution, simulating the blocking behavior in the original example.

  5. The stop() method returns a boolean indicating whether the timer was successfully stopped.

When you run this script, you should see output similar to:

Timer 1 fired
Timer 2 stopped

The first timer will fire ~2s after we start the program, but the second should be stopped before it has a chance to fire.

Note that R doesn’t have built-in concurrency features like goroutines, so this example uses a more traditional approach to timers. The later package is used to schedule future execution of code, which is the closest equivalent to Go’s timer functionality in R.