Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 1692af5

Browse files
fix(loader): Load files concurrently with a limit to avoid "too many open files" errors
1 parent a006c93 commit 1692af5

File tree

2 files changed

+49
-4
lines changed

2 files changed

+49
-4
lines changed

lua/orgmode/files/init.lua

+2-4
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,14 @@ function OrgFiles:load(force)
3939
end
4040

4141
self.load_state = 'loading'
42-
local actions = vim.tbl_map(function(filename)
42+
return Promise.map(function(filename)
4343
return self:load_file(filename):next(function(orgfile)
4444
if orgfile then
4545
self.files[orgfile.filename] = orgfile
4646
end
4747
return orgfile
4848
end)
49-
end, self:_files(true))
50-
51-
return Promise.all(actions):next(function()
49+
end, self:_files(true), 50):next(function()
5250
self.load_state = 'loaded'
5351
return self
5452
end)

lua/orgmode/utils/promise.lua

+47
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,53 @@ function Promise.all(list)
332332
end)
333333
end
334334

335+
--- Equivalents to JavaScript's Promise.map with concurrency limit.
336+
--- @param callback fun(value: any, index: number, array: any[]): any
337+
--- @param list any[]: promise or non-promise values
338+
--- @param concurrency? number: limit number of concurrent items processing
339+
--- @return OrgPromise
340+
function Promise.map(callback, list, concurrency)
341+
vim.validate({
342+
list = { list, 'table' },
343+
callback = { callback, 'function' },
344+
concurrency = { concurrency, 'number', true },
345+
})
346+
347+
local results = {}
348+
local processing = 0
349+
local index = 1
350+
concurrency = concurrency or #list
351+
352+
return Promise.new(function(resolve, reject)
353+
local function processNext()
354+
if index > #list then
355+
if processing == 0 then
356+
resolve(results)
357+
end
358+
return
359+
end
360+
361+
local i = index
362+
index = index + 1
363+
processing = processing + 1
364+
365+
Promise.resolve(callback(list[i], i, list))
366+
:next(function(...)
367+
results[i] = ...
368+
processing = processing - 1
369+
processNext()
370+
end)
371+
:catch(function(...)
372+
reject(...)
373+
end)
374+
end
375+
376+
for _ = 1, concurrency do
377+
processNext()
378+
end
379+
end)
380+
end
381+
335382
--- Equivalents to JavaScript's Promise.race.
336383
--- @param list any[]: promise or non-promise values
337384
--- @return OrgPromise

0 commit comments

Comments
 (0)