Skip to content

Commit

Permalink
fix(async): make asyncs abortable
Browse files Browse the repository at this point in the history
  • Loading branch information
folke committed Jun 30, 2024
1 parent c882227 commit 1fad617
Show file tree
Hide file tree
Showing 7 changed files with 29 additions and 8 deletions.
21 changes: 17 additions & 4 deletions lua/lazy/async.lua
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ end
function Async:suspend(yield)
self._suspended = true
if coroutine.running() == self._co and yield ~= false then
coroutine.yield()
M.yield()
end
end

Expand Down Expand Up @@ -132,12 +132,25 @@ function Async:step()
return self:running()
end

function M.abort()
for _, async in ipairs(M._active) do
coroutine.resume(async._co, "abort")
end
end

function M.yield()
if coroutine.yield() == "abort" then
error("aborted", 2)
end
end

function M.step()
local start = vim.uv.hrtime()
for _ = 1, #M._active do
if vim.uv.hrtime() - start > M.BUDGET * 1e6 then
if Util.exiting() or vim.uv.hrtime() - start > M.BUDGET * 1e6 then
break
end

local state = table.remove(M._active, 1)
if state:step() then
if state._suspended then
Expand All @@ -153,7 +166,7 @@ function M.step()
end

-- M.debug()
if #M._active == 0 then
if #M._active == 0 or Util.exiting() then
return M._executor:stop()
end
end
Expand Down Expand Up @@ -183,7 +196,7 @@ function M.add(async)
end

function M._run()
if not M._executor:is_active() then
if not Util.exiting() and not M._executor:is_active() then
M._executor:start(vim.schedule_wrap(M.step))
end
end
Expand Down
4 changes: 4 additions & 0 deletions lua/lazy/core/util.lua
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ function M.track(data, time)
end
end

function M.exiting()
return vim.v.exiting ~= vim.NIL
end

---@generic T
---@param list T[]
---@param fn fun(v: T):boolean?
Expand Down
2 changes: 1 addition & 1 deletion lua/lazy/manage/process.lua
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ function Process:_run()
end)
self:suspend()
while not (self.handle:is_closing() and stdout:is_closing() and stderr:is_closing()) do
coroutine.yield()
Async.yield()
end
else
self.data = "Failed to spawn process " .. self.cmd .. " " .. vim.inspect(self.opts)
Expand Down
3 changes: 2 additions & 1 deletion lua/lazy/view/float.lua
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ end
---@param fn fun(self?)
---@param desc? string
---@param mode? string[]
function M:on_key(key, fn, desc,mode)
function M:on_key(key, fn, desc, mode)
vim.keymap.set(mode or "n", key, function()
fn(self)
end, {
Expand Down Expand Up @@ -295,6 +295,7 @@ function M:close(opts)
vim.diagnostic.reset(Config.ns, buf)
vim.api.nvim_buf_delete(buf, { force = true })
end
vim.cmd.redraw()
end)
end

Expand Down
1 change: 1 addition & 0 deletions lua/lazy/view/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ function M.create()

vim.keymap.set("n", ViewConfig.keys.abort, function()
require("lazy.manage.process").abort()
require("lazy.async").abort()
return ViewConfig.keys.abort
end, { silent = true, buffer = self.buf, expr = true })

Expand Down
3 changes: 2 additions & 1 deletion tests/manage/runner_spec.lua
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
local Async = require("lazy.async")
local Runner = require("lazy.manage.runner")

describe("runner", function()
Expand Down Expand Up @@ -33,7 +34,7 @@ describe("runner", function()
---@async
---@param task LazyTask
run = function(task)
coroutine.yield()
Async.yield()
table.insert(runs, { plugin = task.plugin.name, task = task.name })
end,
}
Expand Down
3 changes: 2 additions & 1 deletion tests/manage/task_spec.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
--# selene:allow(incorrect_standard_library_use)
local Async = require("lazy.async")
local Task = require("lazy.manage.task")

describe("task", function()
Expand Down Expand Up @@ -42,7 +43,7 @@ describe("task", function()
local running = true
---@async
local task = Task.new(plugin, "test", function()
coroutine.yield()
Async.yield()
running = false
end, opts)
assert(task:running())
Expand Down

0 comments on commit 1fad617

Please sign in to comment.