lua-users home
lua-l archive

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


On Fri, May 11, 2012 at 2:27 PM, Tim Caswell <tim@creationix.com> wrote:
> I mean I don't want to call `sleep(10)` and suddenly be suspended till 10
> seconds later when the timeout occurs.  The problem with this is any
> function that I call could in turn call something else that implicitly
> suspends me.  Your wrapper is plenty explicit.

Here's the problem case:

function web_server:handle_login_html(req)
    -- Grab the current session and ensure it's valid
    local session_data = this:find_session(req) or this:die()
    -- Log the request
    this:log(req)
    -- delegate to session
    session_data:handle_login(req)
end

The problem is "this:log(req)". Logging could be implemented by
writing to a socket--and you can't tell by looking at this code. If it
writes to a socket, the socket may want to block. In a simple socket
coroutine system, operations which would block instead are suspended
until the socket can be read or written. Waiting for this:log() could
take arbitrarily long. The session_data we grabbed at the top may be
stale by then.

Adding to the fun, *most* of the time the log socket will probably be
ready to write; only under load will two identical requests end up
going separate ways.

I hadn't thought about how the coroutine style preserves the stack,
which is nice. But transparently converting blocking operations to
coroutine dispatch can give you back many of the concurrency problems
when you aren't expecting them. I guess neither should be surprising;
it's non-preemptive green threads.

Jay