[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Idea for an event loop library
- From: Graham Wakefield <wakefield@...>
- Date: Fri, 11 May 2012 12:51:24 -0700
Even if no yield/resume is used, since session_data encapsulates some data which are external to Lua, its contents could have been modified between any two ordinary Lua instructions; session_data:handle_login() should be implemented to throw an error if the session_data contents have become invalid. The same applies to a callback-based system; the session_data object still needs to be checked for consistency whenever it is used.
Where the implicit coroutine yield approach can be problematic is when the user expects a non-local pure Lua object to contain the same values before and after this:log(). It can be a big gotcha, but the clarity of exposition and preservation of the stack might be worth it.
On May 11, 2012, at 12:21 PM, Jay Carlson wrote:
> 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
>