Working in lua, I have a table of key/value pairs
local fmtsToRun = {
name = function()
return configSubTable
end
}
Which could be 1 or more entries in length. I need to loop through each entry and run a subprocess (through some libuv C bindings).
With a normal for loop, the subprocess results from libuv return after the loop has finished running, leading to things showing up out of order. The result would be
- Loop Start
- Loop Entry 1
- Job 1 starts
- Loop Entry 2
- Job 2 starts
- Loop Ends
- Job1 Returns
- Job2 Returns
What I need to have is
- Loop Start
- Loop Entry 1
- Job 1 starts
- Job1 Returns
- Loop Entry 2
- Job 2 starts
- Job2 Returns
- Loop Ends
I've also tried writing my own version of pairs()
to and using something like coroutines to handle the callbacks
for fmt, output in jobIterator(fmtsToRun) do
print('finished running', output)
end
local function jobIterator(tbl)
return coroutine.wrap(function()
local fmtConf, fmtName
fmtName, fmtConf = next(tbl, fmtName)
if nil~=fmtConf then
local conf = fmtConf()
local output = nil
-- wrapper util from Libuv library
local job = Job:new({
cmd = conf.cmd,
args = conf.args,
on_stdout = onStdout, -- process output
on_stderr = onStderr, -- process any error
on_exit = function()
coroutine.yield(fmtName, output)
end
})
job.send(conf.data)
end
end)
end
which leads to this error messages.
attempt to yield across C-call boundary
What would be the "right" way to wait for the job
to finish and continue the loop while maintaining the correct order?