On Thu, Jul 11, 2013 at 11:56 PM, William Ahern <email@example.com> wrote:
IME, callbacks of any kind are to be avoided if at all possible. Absolutelyeverything is simpler in a more functional, call-and-return style. This why
coroutines in Lua can be so powerful; often they're used to invert
contination callbacks so you can use an easier consumer design pattern in
Lua code. But if possible it's best to avoid all the trouble entirely at the
C or C++ layer.
This is also why message passing designs are preferred by myself and others.
The OS primitives are built so that each actors executes a pull its consumer
role, and a push in its producer role, with the OS intermediating.I heartily second this. The asynchronous strategy I use is to have a separate thread for any parallel blocking I/O that wakes up a coroutine in the main thread when things are ready. I only need a single lua state, and all the complex logic runs in coroutines where the cooperative scheduling nature of coroutines allows me to completely avoid all the crazy locking issues you have with regular threaded applications. Coroutines communicate with simple message queues implemented entirely in lua no locking needed. The code that runs in separate threads is simple and low level and independent. I've been pleasantly surprised at how reliable and trouble free this approach has been. Using coroutines allows you to write in a straightforward imperative style without breaking your logic up into odd bits and pieces as you tend to do with event driven and callback oriented approaches.