feat(git): added git network throttle to limit network related git ops per interval. Closes #1635

This commit is contained in:
Folke Lemaitre 2024-07-16 16:50:31 +02:00
parent 9d445ebbd8
commit d731a6b005
No known key found for this signature in database
GPG Key ID: 41F8B1FBACAE2040
2 changed files with 47 additions and 0 deletions

View File

@ -34,6 +34,13 @@ M.defaults = {
-- then set the below to false. This should work, but is NOT supported and will -- then set the below to false. This should work, but is NOT supported and will
-- increase downloads a lot. -- increase downloads a lot.
filter = true, filter = true,
-- rate of network related git operations (clone, fetch, checkout)
throttle = {
enabled = false, -- not enabled by default
-- max 2 ops every 5 seconds
rate = 2,
duration = 5 * 1000, -- in ms
},
}, },
pkg = { pkg = {
enabled = true, enabled = true,

View File

@ -1,8 +1,45 @@
local Async = require("lazy.async")
local Config = require("lazy.core.config") local Config = require("lazy.core.config")
local Git = require("lazy.manage.git") local Git = require("lazy.manage.git")
local Lock = require("lazy.manage.lock") local Lock = require("lazy.manage.lock")
local Util = require("lazy.util") local Util = require("lazy.util")
local throttle = {}
throttle.running = 0
throttle.waiting = {} ---@type Async[]
throttle.timer = vim.uv.new_timer()
function throttle.next()
throttle.running = 0
while #throttle.waiting > 0 and throttle.running < Config.options.git.throttle.rate do
---@type Async
local task = table.remove(throttle.waiting, 1)
task:resume()
throttle.running = throttle.running + 1
end
if throttle.running == 0 then
throttle.timer:stop()
end
end
function throttle.wait()
if not Config.options.git.throttle.enabled then
return
end
if not throttle.timer:is_active() then
throttle.timer:start(0, Config.options.git.throttle.duration, vim.schedule_wrap(throttle.next))
end
local running = Async.running()
if throttle.running < Config.options.git.throttle.rate then
throttle.running = throttle.running + 1
else
table.insert(throttle.waiting, running)
coroutine.yield("waiting")
running:suspend()
coroutine.yield("")
end
end
---@type table<string, LazyTaskDef> ---@type table<string, LazyTaskDef>
local M = {} local M = {}
@ -84,6 +121,7 @@ M.clone = {
end, end,
---@async ---@async
run = function(self) run = function(self)
throttle.wait()
local args = { local args = {
"clone", "clone",
self.plugin.url, self.plugin.url,
@ -233,6 +271,7 @@ M.fetch = {
---@async ---@async
run = function(self) run = function(self)
throttle.wait()
local args = { local args = {
"fetch", "fetch",
"--recurse-submodules", "--recurse-submodules",
@ -262,6 +301,7 @@ M.checkout = {
---@async ---@async
---@param opts {lockfile?:boolean} ---@param opts {lockfile?:boolean}
run = function(self, opts) run = function(self, opts)
throttle.wait()
local info = assert(Git.info(self.plugin.dir)) local info = assert(Git.info(self.plugin.dir))
local target = assert(Git.get_target(self.plugin)) local target = assert(Git.get_target(self.plugin))