lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Thu, Jul 11, 2013 at 10:27:01PM -0500, Andrew Starks wrote:
> On Thu, Jul 11, 2013 at 4:06 PM, Sean Conner <sean@conman.org> wrote:
<snip>
> >
> >> Most importantly, we're hoping that:
> >>
> >> 3: This is a well-worn path and that other people use this strategy,
> >> quite regularly.
> >
> >   Personally, I tend to give each OS thread its own Lua state, using a
> > "no-share" model of computation.  Yes, it means copying data through a
> > message, but the slowness of that approach isn't as slow as many people
> > think [1].  I also think it's easier to reason about the resulting code.
> >
> >   -spc
> >
> > [1]     QNX is a message-based OS, and back in the 90s, a company
> >         (disclaimer: I knew the owners) who sold X servers said their
> >         *fastest* implementation was on QNX.
> >
> 
> Thanks Sean. I think that your suggestion is where we'll end up. In
> order to avoid tackling serialization and possibly a library (such as
> ZMQ), and given that we're already dealing with a highly parallel API,
> this felt like a smaller first step. We're *mostly* not sharing state,
> at least. :)
> 

ZMQ? That seems like overkill. If you're on Linux and your objects are
principally in C or C++, you can simply use regular threading primitives
along with eventfd() for signaling.

IME, callbacks of any kind are to be avoided if at all possible. Absolutely
everything 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. But you
don't need to use sockets or regular I/O primitives to accomplish this. You
can do it with a simple lists of messages and an OS signaling primitive
(either with regular POSIX locking for 1:1, or on Linux eventfd for 1:N
signaling).

Threaded callbacks especially are evil. libevent, perhaps the most used
event library for server software, has been plagued with bugs because of the
way it mixes callbacks and threading.