Skip to content

Commit d731a6b

Browse files
committed
feat(git): added git network throttle to limit network related git ops per interval. Closes #1635
1 parent 9d445eb commit d731a6b

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

lua/lazy/core/config.lua

+7
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ M.defaults = {
3434
-- then set the below to false. This should work, but is NOT supported and will
3535
-- increase downloads a lot.
3636
filter = true,
37+
-- rate of network related git operations (clone, fetch, checkout)
38+
throttle = {
39+
enabled = false, -- not enabled by default
40+
-- max 2 ops every 5 seconds
41+
rate = 2,
42+
duration = 5 * 1000, -- in ms
43+
},
3744
},
3845
pkg = {
3946
enabled = true,

lua/lazy/manage/task/git.lua

+40
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,45 @@
1+
local Async = require("lazy.async")
12
local Config = require("lazy.core.config")
23
local Git = require("lazy.manage.git")
34
local Lock = require("lazy.manage.lock")
45
local Util = require("lazy.util")
56

7+
local throttle = {}
8+
throttle.running = 0
9+
throttle.waiting = {} ---@type Async[]
10+
throttle.timer = vim.uv.new_timer()
11+
12+
function throttle.next()
13+
throttle.running = 0
14+
while #throttle.waiting > 0 and throttle.running < Config.options.git.throttle.rate do
15+
---@type Async
16+
local task = table.remove(throttle.waiting, 1)
17+
task:resume()
18+
throttle.running = throttle.running + 1
19+
end
20+
if throttle.running == 0 then
21+
throttle.timer:stop()
22+
end
23+
end
24+
25+
function throttle.wait()
26+
if not Config.options.git.throttle.enabled then
27+
return
28+
end
29+
if not throttle.timer:is_active() then
30+
throttle.timer:start(0, Config.options.git.throttle.duration, vim.schedule_wrap(throttle.next))
31+
end
32+
local running = Async.running()
33+
if throttle.running < Config.options.git.throttle.rate then
34+
throttle.running = throttle.running + 1
35+
else
36+
table.insert(throttle.waiting, running)
37+
coroutine.yield("waiting")
38+
running:suspend()
39+
coroutine.yield("")
40+
end
41+
end
42+
643
---@type table<string, LazyTaskDef>
744
local M = {}
845

@@ -84,6 +121,7 @@ M.clone = {
84121
end,
85122
---@async
86123
run = function(self)
124+
throttle.wait()
87125
local args = {
88126
"clone",
89127
self.plugin.url,
@@ -233,6 +271,7 @@ M.fetch = {
233271

234272
---@async
235273
run = function(self)
274+
throttle.wait()
236275
local args = {
237276
"fetch",
238277
"--recurse-submodules",
@@ -262,6 +301,7 @@ M.checkout = {
262301
---@async
263302
---@param opts {lockfile?:boolean}
264303
run = function(self, opts)
304+
throttle.wait()
265305
local info = assert(Git.info(self.plugin.dir))
266306
local target = assert(Git.get_target(self.plugin))
267307

0 commit comments

Comments
 (0)