Search code examples
luacoroutine

Supervising coroutines in Lua


I have written a code that runs multiple tasks one after the other in Lua. There is simply a loop that calls each function and then use the output for the next one and so on. Usually there is no issue, but it happens that there is some error. In these situations the code would just stop working.

What I want is to monitor my code. In case there is an error at some point, I can call plan B and avoid that the program interrupts.

I've read about Lua coroutines, and it appears to be what i am looking for. If there is an error, the coroutine returns the error.

My question is whether I can stop coroutine that last too long. Lua offers asynchronous coroutines, so I thought that I cannot execute a function and simultaneously compute how long it has been busy doing the task. Am I getting this right, or is there a way to basically stop coroutines from the outside with some condition ?

Thank you


Solution

  • This is not possible using Lua coroutines. Lua coroutines are cooperative; they do not (inherently) support preemption, which is what you're looking for. For a coroutine to return execution to the caller of coroutine.resume, it has to "cooperate" by calling coroutine.yield or error.

    As has been pointed out in the comments, it is possible to set a line hook - or even an "instruction hook" - to implement preemption of Lua-only code, by interrupting the code on every new line / every couple instructions executed and checking whether a timeout is met.

    This stops working as soon as you call a (blocking) C function, including Lua standard library functions; it only works well for "pure Lua" code which only does constant-time API calls, since the API call is just a single line of code / instruction for Lua; Lua has no view "into" the function.

    To solve this issue, you'll need actual multithreading e.g. using lualanes, multiprocessing (e.g. using luaposix's fork), or a nonblocking API and polling.