Timers in Nim

import times, asyncdispatch

proc main() {.async.} =
  # Timers represent a single event in the future. You
  # tell the timer how long you want to wait, and it
  # provides a way to be notified at that time.
  # This timer will wait 2 seconds.
  let timer1 = sleepAsync(2000)
  
  # The `await timer1` blocks until the timer fires.
  await timer1
  echo "Timer 1 fired"
  
  # If you just wanted to wait, you could have used
  # `sleep`. One reason a timer may be useful is
  # that you can cancel the timer before it fires.
  # Here's an example of that.
  var timer2 = sleepAsync(1000)
  
  proc checkTimer2() {.async.} =
    await timer2
    echo "Timer 2 fired"
  
  asyncCheck checkTimer2()
  
  # Cancel the timer
  timer2.cancel()
  echo "Timer 2 stopped"
  
  # Give the `timer2` enough time to fire, if it ever
  # was going to, to show it is in fact stopped.
  await sleepAsync(2000)

waitFor main()

We often want to execute code at some point in the future, or repeatedly at some interval. Nim’s asyncdispatch module provides features that make both of these tasks easy. We’ll look at timers in this example.

In this Nim program:

  1. We import the times and asyncdispatch modules, which provide the necessary timing and asynchronous functions.

  2. We define an asynchronous main procedure using the {.async.} pragma.

  3. We create a timer using sleepAsync(2000), which will wait for 2 seconds (2000 milliseconds).

  4. We use await timer1 to block until the timer fires.

  5. We demonstrate cancelling a timer by creating a second timer and then immediately cancelling it.

  6. We use asyncCheck to start an asynchronous operation without waiting for it to complete.

  7. Finally, we use waitFor main() to run the asynchronous main procedure.

To run the program, save it as timers.nim and use the Nim compiler:

$ nim c -r timers.nim
Timer 1 fired
Timer 2 stopped

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

This example demonstrates basic timer usage in Nim, including creating, waiting for, and cancelling timers in an asynchronous context.