lua-users home
lua-l archive

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

On 11/05/12 16:21, Jay Carlson wrote:
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
     -- delegate to session

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.

In my library you handle this case the obvious 2 ways: you create separate task when invoking the log function, or have a separate logging task running and signal it when you want to log something.

--Option A:
local function log(req)
function handle_login_html(req)
    local session=find_session(req) or error(), req)

--Option B
function handle_login_html(req)
    local session=find_session(req) or error()
    sched.signal("logthis!", req)

In both cases if the logging function blocks, control will be dispatched back (eventually). In other words, if you want synchronous, then do function calls. If you want asynchronous, create tasks or signals. Of course, this makes no sense if i live under the fear that any function call i do can turn into a horrible beast. But anyway I can handle only so much complexity and levels of indirection. The whole reason behind this library was to see if I can cram everyhing needed in such a compact package that i can handle an application completelly. It is still cooperative multitasking, after all.