Skip to content

Commit

Permalink
fix(tasks): cancel immediately
Browse files Browse the repository at this point in the history
Previously the loop would wait for the next yield but instead we can
just step forward immediately when cancelling.

See #15
  • Loading branch information
rcarriga committed Apr 29, 2024
1 parent 7fa5545 commit 79e8968
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 1 deletion.
4 changes: 3 additions & 1 deletion lua/nio/tasks.lua
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ end
function nio.tasks.run(func, cb)
local co = coroutine.create(func)
local cancelled = false
local step
local task = { parent = nio.tasks.current_task() }
if task.parent then
child_tasks[task.parent] = child_tasks[task.parent] or {}
Expand All @@ -75,6 +76,7 @@ function nio.tasks.run(func, cb)
child.cancel()
end
cancelled = true
step()
end

function task.trace()
Expand Down Expand Up @@ -104,7 +106,7 @@ function nio.tasks.run(func, cb)

tasks[co] = task

local function step(...)
step = function(...)
if cancelled then
close_task(nil, format_error("Task was cancelled"))
return
Expand Down
18 changes: 18 additions & 0 deletions tests/tasks_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,24 @@ describe("task", function()
assert.Nil(should_be_nil)
end)

a.it("cancels immediately", function()
local cancelled = nio.control.future()
local start = os.time()
local reached_end = false

local task = tasks.run(function()
nio.sleep(1000)
reached_end = true
end, function()
cancelled.set(os.time())
end)
task.cancel()
local cancel_time = cancelled.wait()

assert.False(reached_end)
assert.Equal(cancel_time - start, 0)
end)

a.it("assigns parent task", function()
local current = tasks.current_task()
local task = tasks.run(function()
Expand Down

0 comments on commit 79e8968

Please sign in to comment.