12

I would like to create a timer using Lua, in a way that I could specify a callback function to be triggered after X seconds have passed.

What would be the best way to achieve this? ( I need to download some data from a webserver that will be parsed once or twice an hour )

Cheers.

6 Answers 6

9

If milisecond accuracy is not needed, you could just go for a coroutine solution, which you resume periodically, like at the end of your main loop, Like this:

require 'socket' -- for having a sleep function ( could also use os.execute(sleep 10))
timer = function (time)
    local init = os.time()
    local diff=os.difftime(os.time(),init)
    while diff<time do
        coroutine.yield(diff)
        diff=os.difftime(os.time(),init)
    end
    print( 'Timer timed out at '..time..' seconds!')
end
co=coroutine.create(timer)
coroutine.resume(co,30) -- timer starts here!
while coroutine.status(co)~="dead" do
    print("time passed",select(2,coroutine.resume(co)))
    print('',coroutine.status(co))
    socket.sleep(5)
end

This uses the sleep function in LuaSocket, you could use any other of the alternatives suggested on the Lua-users Wiki

Sign up to request clarification or add additional context in comments.

Comments

5

Try lalarm, here: http://www.tecgraf.puc-rio.br/~lhf/ftp/lua/

Example (based on src/test.lua):

-- alarm([secs,[func]])
alarm(1, function() print(2) end); print(1)

Output:

1
2

3 Comments

Could you give me an example of how to use alarm in a simple way to call a function every minute?
Did you look at the code? There is a file "test.lua" in the lalarm archive.
It's not possible to set to two alarms in a row, otherwise the second would overhide the first one.
1

If it's acceptable for you, you can try LuaNode. The following code sets a timer:

setInterval(function()
    console.log("I run once a minute")
end, 60000)
process:loop()

Comments

1

After reading this thread and others I decided to go with Luv lib. Here is my solution:

uv = require('luv') --luarocks install luv

function set_timeout(timeout, callback)
  local timer = uv.new_timer()
  local function ontimeout()
    uv.timer_stop(timer)
    uv.close(timer)
    callback()
  end
  uv.timer_start(timer, timeout, 0, ontimeout)
  return timer
end


set_timeout(1000, function() print('ok') end) -- time in ms

uv.run() --it will hold at this point until every timer have finished

Comments

0

use Script.SetTimer(interval, callbackFunction)

Comments

0

On my Debian I've install lua-lgi packet to get access to the GObject based libraries.

The following code show you an usage demonstrating that you can use few asynchronuous callbacks:

local lgi = require 'lgi'
local GLib = lgi.GLib

-- Get the main loop object that handles all the events
local main_loop = GLib.MainLoop()

cnt = 0
function tictac()
     cnt = cnt + 1
     print("tic")
     -- This callback will be called until the condition is true
     return cnt < 10
end

-- Call tictac function every 2 senconds
GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 2, tictac)

-- You can also use an anonymous function like that
GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 1,
                         function()
                            print( "There have been ", cnt, "tic")
                            -- This callback will never stop
                            return true
                         end)

-- Once everything is setup, you can start the main loop
main_loop:run()

-- Next instructions will be still interpreted
print("Main loop is running")

You can find more documentation about LGI here

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.