mirror of
https://github.com/NotAShelf/direnv.nvim.git
synced 2025-10-02 23:13:34 +00:00
add request deduplication to prevent concurrent direnv status calls
We would like to prevent multiple simultaneous direnv status requests, which we do by queuing callbacks and using a pending_request flag. Makes it so that all waiting callbacks receive the same result when the request completes.
This commit is contained in:
parent
a2f1264909
commit
eab8a55ea8
1 changed files with 38 additions and 5 deletions
|
@ -20,9 +20,11 @@ local cache = {
|
||||||
path = nil,
|
path = nil,
|
||||||
last_check = 0,
|
last_check = 0,
|
||||||
ttl = 5000, -- milliseconds before cache invalidation, then we can think about naming things
|
ttl = 5000, -- milliseconds before cache invalidation, then we can think about naming things
|
||||||
|
pending_request = false,
|
||||||
}
|
}
|
||||||
|
|
||||||
local notification_queue = {}
|
local notification_queue = {}
|
||||||
|
local pending_callbacks = {}
|
||||||
|
|
||||||
--- Check if an executable is available in PATH
|
--- Check if an executable is available in PATH
|
||||||
--- @param executable_name string Name of the executable
|
--- @param executable_name string Name of the executable
|
||||||
|
@ -116,16 +118,32 @@ end
|
||||||
M._get_rc_status = function(callback)
|
M._get_rc_status = function(callback)
|
||||||
local loop = vim.uv or vim.loop
|
local loop = vim.uv or vim.loop
|
||||||
local now = math.floor(loop.hrtime() / 1000000) -- ns -> ms
|
local now = math.floor(loop.hrtime() / 1000000) -- ns -> ms
|
||||||
|
|
||||||
if cache.status ~= nil and (now - cache.last_check) < cache.ttl then
|
if cache.status ~= nil and (now - cache.last_check) < cache.ttl then
|
||||||
return callback(cache.status, cache.path)
|
return callback(cache.status, cache.path)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
table.insert(pending_callbacks, callback)
|
||||||
|
|
||||||
|
if cache.pending_request then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
cache.pending_request = true
|
||||||
|
|
||||||
local cwd = get_cwd()
|
local cwd = get_cwd()
|
||||||
if not cwd then
|
if not cwd then
|
||||||
return callback(nil, nil)
|
cache.pending_request = false
|
||||||
|
for _, cb in ipairs(pending_callbacks) do
|
||||||
|
cb(nil, nil)
|
||||||
|
end
|
||||||
|
pending_callbacks = {}
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local on_exit = function(obj)
|
local on_exit = function(obj)
|
||||||
|
cache.pending_request = false
|
||||||
|
|
||||||
if obj.code ~= 0 then
|
if obj.code ~= 0 then
|
||||||
vim.schedule(function()
|
vim.schedule(function()
|
||||||
notify(
|
notify(
|
||||||
|
@ -134,26 +152,41 @@ M._get_rc_status = function(callback)
|
||||||
vim.log.levels.ERROR
|
vim.log.levels.ERROR
|
||||||
)
|
)
|
||||||
end)
|
end)
|
||||||
return callback(nil, nil)
|
for _, cb in ipairs(pending_callbacks) do
|
||||||
|
cb(nil, nil)
|
||||||
|
end
|
||||||
|
pending_callbacks = {}
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local ok, status = pcall(vim.json.decode, obj.stdout)
|
local ok, status = pcall(vim.json.decode, obj.stdout)
|
||||||
if not ok or not status or not status.state then
|
if not ok or not status or not status.state then
|
||||||
return callback(nil, nil)
|
for _, cb in ipairs(pending_callbacks) do
|
||||||
|
cb(nil, nil)
|
||||||
|
end
|
||||||
|
pending_callbacks = {}
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if status.state.foundRC == vim.NIL then
|
if status.state.foundRC == vim.NIL then
|
||||||
cache.status = nil
|
cache.status = nil
|
||||||
cache.path = nil
|
cache.path = nil
|
||||||
cache.last_check = now
|
cache.last_check = now
|
||||||
return callback(nil, nil)
|
for _, cb in ipairs(pending_callbacks) do
|
||||||
|
cb(nil, nil)
|
||||||
|
end
|
||||||
|
pending_callbacks = {}
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
cache.status = status.state.foundRC.allowed
|
cache.status = status.state.foundRC.allowed
|
||||||
cache.path = status.state.foundRC.path
|
cache.path = status.state.foundRC.path
|
||||||
cache.last_check = now
|
cache.last_check = now
|
||||||
|
|
||||||
callback(status.state.foundRC.allowed, status.state.foundRC.path)
|
for _, cb in ipairs(pending_callbacks) do
|
||||||
|
cb(status.state.foundRC.allowed, status.state.foundRC.path)
|
||||||
|
end
|
||||||
|
pending_callbacks = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
vim.system(
|
vim.system(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue