The coroutine structure maybe a little bit confusing because you have to realize that the whole bot already running inside a coroutine, and yrest basically calls coroutine.yield but more imported is that the functions from the Timer also runs in another coroutine.
So one thing is the timer(s) depends on coroutines the other is through the fact that only one coroutine can run at the time you can effectively suspend the other coroutines / put them in wait , without the coroutine framework you don't have this.
Theoretically admin could run the timer between the calls manually but one timer isn't enough, when I'm thinking about GMList()
The point is you would need also call the timed functions short so that normal things can also run. Here a picture for better understanding:

I implemented a solution for this in another class without coroutines, you simple call it after the "normal" state call.
It has a time disk and you can set a maximum how much time the whole disk can consume, a parallel to yrest I added an example on the bottom of the file.