🎓 A1Learner
🔍
0 of 49 lessons completed

Lua Coroutine Timeouts

A cooperative timeout is a deadline a scheduler enforces with a simulated tick counter. The scheduler advances the counter itself, and it stops resuming a task once the counter passes the task deadline.

A tick counter advances each round

The scheduler adds one to the tick on every round and prints it. The count is fully predictable.

local tick = 0
for _ = 1, 3 do
  tick = tick + 1
  print(tick)
end

A task past its deadline times out

The task needs five steps but its deadline is tick 3. The scheduler stops at tick 3 and reports the timeout.

local tick = 0
local deadline = 3
local task = coroutine.create(function()
  for i = 1, 5 do
    print("step " .. i)
    coroutine.yield()
  end
end)
while coroutine.status(task) ~= "dead" do
  tick = tick + 1
  if tick > deadline then
    print("timed out")
    break
  end
  coroutine.resume(task)
end

A task inside its deadline finishes

This task needs two steps and its deadline is tick 3. It finishes on tick 2, before any timeout.

local tick = 0
local deadline = 3
local task = coroutine.create(function()
  for i = 1, 2 do
    print("step " .. i)
    coroutine.yield()
  end
end)
while coroutine.status(task) ~= "dead" do
  tick = tick + 1
  if tick > deadline then
    print("timed out")
    break
  end
  coroutine.resume(task)
end
print("done")

Example

local function run(task, deadline)
  local tick = 0
  while coroutine.status(task) ~= "dead" do
    tick = tick + 1
    if tick > deadline then
      print("timed out at tick " .. tick)
      return
    end
    coroutine.resume(task)
  end
  print("finished at tick " .. tick)
end
local slow = coroutine.create(function()
  for i = 1, 5 do
    print("slow step " .. i)
    coroutine.yield()
  end
end)
local fast = coroutine.create(function()
  for i = 1, 2 do
    print("fast step " .. i)
    coroutine.yield()
  end
end)
run(slow, 3)
run(fast, 3)

Key points

  • Tick: a counter the scheduler advances by one on each round, standing in for passing time.
  • Deadline: the tick value by which a task must finish.
  • Timeout: what happens when the tick passes a task deadline before the task finishes.
  • Cooperative: the task only stops at a yield, since the scheduler cannot interrupt it mid-step.
  • Check point: the scheduler compares the tick with each deadline before every resume.

In this example, each run keeps its own tick counter and a deadline of 3. The slow task prints three steps, then tick 4 passes its deadline, so it times out. The fast task prints two steps and finishes on its third resume, inside its deadline.

Note

no real clock is used here, so the same run always gives the same result.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

A task has deadline tick 2 and needs 4 steps, one step per tick. What happens?