-
Notifications
You must be signed in to change notification settings - Fork 72
/
Copy pathparallel.lua
105 lines (100 loc) · 2.75 KB
/
parallel.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
local parser = require("overseer.parser")
local parser_util = require("overseer.parser.util")
local Parallel = {
desc = "Run the child nodes in parallel",
long_desc = "The children are still run in-order, it just means that the input lines are fed to all the children on every iteration",
doc_args = {
{
name = "opts",
type = "object",
desc = "Configuration options",
position_optional = true,
fields = {
{
name = "break_on_first_failure",
type = "boolean",
desc = "Stop executing as soon as a child returns FAILURE",
default = true,
},
{
name = "break_on_first_success",
type = "boolean",
desc = "Stop executing as soon as a child returns SUCCESS",
default = false,
},
{
name = "reset_children",
type = "boolean",
desc = "Reset all children at the beginning of each iteration",
default = false,
},
},
},
{
name = "child",
type = "parser",
vararg = true,
desc = "The child parser nodes. Can be passed in as varargs or as a list.",
},
},
}
function Parallel.new(opts, ...)
local children
if parser_util.is_parser(opts) then
children = vim.F.pack_len(opts, ...)
opts = {}
else
children = vim.F.pack_len(...)
end
vim.validate({
break_on_first_failure = { opts.break_on_first_failure, "b", true },
break_on_first_success = { opts.break_on_first_success, "b", true },
reset_children = { opts.reset_children, "b", true },
})
opts = vim.tbl_deep_extend("keep", opts, {
break_on_first_failure = true,
break_on_first_success = false,
reset_children = false,
})
return setmetatable({
break_on_first_success = opts.break_on_first_success,
break_on_first_failure = opts.break_on_first_failure,
reset_children = opts.reset_children,
children = parser_util.hydrate_list(children),
}, { __index = Parallel })
end
function Parallel:reset()
for _, child in ipairs(self.children) do
child:reset()
end
end
function Parallel:ingest(...)
local any_failed = false
local any_running = false
for _, child in ipairs(self.children) do
if self.reset_children then
child:reset()
end
local st = child:ingest(...)
if st == parser.STATUS.SUCCESS then
if self.break_on_first_success then
return st
end
elseif st == parser.STATUS.FAILURE then
if self.break_on_first_failure then
return st
end
any_failed = true
else
any_running = true
end
end
if any_running then
return parser.STATUS.RUNNING
elseif any_failed then
return parser.STATUS.FAILURE
else
return parser.STATUS.SUCCESS
end
end
return Parallel