Timers in Lua

local socket = require("socket")

-- We often want to execute Lua code at some point in the
-- future, or repeatedly at some interval. Lua doesn't have
-- built-in timer features, but we can implement them using
-- the LuaSocket library. We'll look at both one-time timers
-- and recurring timers.

-- Function to create a timer
local function createTimer(delay, callback)
    local startTime = socket.gettime()
    return {
        check = function()
            if socket.gettime() - startTime >= delay then
                callback()
                return true
            end
            return false
        end,
        cancel = function()
            startTime = nil
        end
    }
end

-- This timer will wait 2 seconds.
local timer1 = createTimer(2, function()
    print("Timer 1 fired")
end)

-- We'll use a loop to check if the timer has fired.
while not timer1.check() do
    socket.sleep(0.1)  -- Sleep for a short time to avoid busy-waiting
end

-- If you just wanted to wait, you could have used
-- socket.sleep(). One reason a timer may be useful is
-- that you can cancel the timer before it fires.
-- Here's an example of that.

local timer2 = createTimer(1, function()
    print("Timer 2 fired")
end)

-- We'll start a new coroutine to run the timer
local co = coroutine.create(function()
    while not timer2.check() do
        socket.sleep(0.1)
    end
end)

-- Stop the timer
timer2.cancel()
print("Timer 2 stopped")

-- Give timer2 enough time to fire, if it ever
-- was going to, to show it is in fact stopped.
socket.sleep(2)

To run this program, save it as timers.lua and execute it using the Lua interpreter:

$ lua timers.lua
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 Lua doesn’t have built-in timer functionality like Go does. In this example, we’ve used the LuaSocket library to implement a simple timer system. The createTimer function returns a table with check and cancel methods, which mimic the behavior of Go’s timers.

We use coroutines to simulate Go’s goroutines for the second timer. However, since we immediately cancel the timer, the coroutine doesn’t get a chance to complete.

This implementation is a basic approximation of Go’s timer functionality. In a real-world scenario, you might want to use a more robust timer library or implement a more sophisticated timer system.