* async git watcher reload; callback hell for now

* async git watcher reload; revert unnecessary extractions

* async git watcher reload; callback and non-callback functions are required for sync codepaths that loop

* async git watcher reload

* async git watcher reload

* feat(#1974): experimental.git.async

* feat(#1974): experimental.git.async
This commit is contained in:
Alexander Courtis
2023-04-03 16:20:52 +10:00
committed by GitHub
parent 7ad1c204c4
commit 0ef3d4613f
6 changed files with 173 additions and 73 deletions

View File

@@ -69,7 +69,7 @@ function Runner:_log_raw_output(output)
end
end
function Runner:_run_git_job()
function Runner:_run_git_job(callback)
local handle, pid
local stdout = vim.loop.new_pipe(false)
local stderr = vim.loop.new_pipe(false)
@@ -78,6 +78,9 @@ function Runner:_run_git_job()
local function on_finish(rc)
self.rc = rc or 0
if timer:is_closing() or stdout:is_closing() or stderr:is_closing() or (handle and handle:is_closing()) then
if callback then
callback()
end
return
end
timer:stop()
@@ -91,6 +94,10 @@ function Runner:_run_git_job()
end
pcall(vim.loop.kill, pid)
if callback then
callback()
end
end
local opts = self:_getopts(stdout, stderr)
@@ -142,25 +149,7 @@ function Runner:_wait()
end
end
-- This module runs a git process, which will be killed if it takes more than timeout which defaults to 400ms
function Runner.run(opts)
local profile = log.profile_start("git job %s %s", opts.project_root, opts.path)
local self = setmetatable({
project_root = opts.project_root,
path = opts.path,
list_untracked = opts.list_untracked,
list_ignored = opts.list_ignored,
timeout = opts.timeout or 400,
output = {},
rc = nil, -- -1 indicates timeout
}, Runner)
self:_run_git_job()
self:_wait()
log.profile_end(profile)
function Runner:_finalise(opts)
if self.rc == -1 then
log.line("git", "job timed out %s %s", opts.project_root, opts.path)
timeouts = timeouts + 1
@@ -179,8 +168,55 @@ function Runner.run(opts)
else
log.line("git", "job success %s %s", opts.project_root, opts.path)
end
end
return self.output
--- Runs a git process, which will be killed if it takes more than timeout which defaults to 400ms
--- @param opts table
--- @param callback function|nil executed passing return when complete
--- @return table|nil status by absolute path, nil if callback present
function Runner.run(opts, callback)
local self = setmetatable({
project_root = opts.project_root,
path = opts.path,
list_untracked = opts.list_untracked,
list_ignored = opts.list_ignored,
timeout = opts.timeout or 400,
output = {},
rc = nil, -- -1 indicates timeout
}, Runner)
local async = callback ~= nil and self.config.git_async
local profile = log.profile_start("git %s job %s %s", async and "async" or "sync", opts.project_root, opts.path)
if async and callback then
-- async, always call back
self:_run_git_job(function()
log.profile_end(profile)
self:_finalise(opts)
callback(self.output)
end)
else
-- sync, maybe call back
self:_run_git_job()
self:_wait()
log.profile_end(profile)
self:_finalise(opts)
if callback then
callback(self.output)
else
return self.output
end
end
end
function Runner.setup(opts)
Runner.config = {}
Runner.config.git_async = opts.experimental.git.async
end
return Runner