lua-users home
lua-l archive

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


Hi,


Copas version 1.2.0 has a new function according to the Copas reference documentation.

    copas.sleep(sleeptime)
        sleeptime is optional and defaults to 0.

I assume the function is used for delaying a coroutine for a few seconds, but the documentation lacks examples about how to use it correctly. So I am examining it myself. I created this basic TCP server to see if I can make it work:

01    local copas = require("copas")
02
03    function connection_handler(skt)
04        while true do
05            copas.send(skt, "Please enter something, or type 'quit': ")
06            local data = "">07            if data == "quit" then
08                break
09            end
10            copas.send(skt, "Please wait for 5 seconds...\r\n")
11            copas.sleep(5)
12            copas.send(skt, "Thank you.\r\n")
13        end
14    end
15
16    server = socket.bind("*", 2000)
17    copas.addserver(server, connection_handler)
18
19    while true do
20        copas.step()
21        -- I could add some extra code here later
22    end

I am using Lua 5.1.5. I tried Lua 5.2.3, but that raised a different problem: line #16 couldn't find the global 'socket'. So I simply switched back to 5.1.5.

The problem is, the server only sends a "thank you" when another client connects or sends something. So, the waiting interval can be longer than 5 seconds, and that isn't my intention.

The Copas dispatcher only gives control to a coroutine when a coroutine hands over control to the dispatcher. This is by design. However, if no other coroutines (client) triggers the dispatcher after 5 seconds in order to wake the sleeping coroutine, then who does? The sleeping coroutine can't trigger the dispatcher either, because it is asleep.

I should probably use this Copas 1.2.0 function:

    copas.wakeup(co)
        co is the coroutine to wakeup.

I have no clue to from where in my program to call this function, and how to determine the value of co.

In my humble opinion there are three possible conclusions:

(1) These functions' implementation isn't finished yet. It is however included in the Copas reference, so it in that case it is a bug.
(2) Copas' documentation regarding these functions is incomplete. I always like OpenBSD's statement about this: a program might be working correctly, but incomplete documentation is also a bug.
(3) I myself am making wrong assumptions on how to use this function, or what it is used for.

Meanwhile, I discovered a great mystery. At least, to me it is. The above TCP server program *is* able to work as expected, but only when both of the following changes are made:

(1) replace line #1 by: local copas = require("copas.timer")
(2) replace lines #19 to #22 by: copas.loop()

I know the CopasTimer module does some Copas timing (oh really?) and therefore it might trigger the Copas dispatcher, that's why I gave it a try. But that doesn't explain why change #2 is needed.

The only explanations I could think of here are:

(1) The current Copas is newer than the current CopasTimer. CopasTimer reuses and replaces Copas code: it could be incompatible with the current Copas.
(2) copas.send() and copas.wakeup() aren't new. Using Google I found some old suggestions (including code) for adding these functions to Copas. So, CopasTimer could have adapted these future changes only to copas.loop().

I am curious to other people's views and suggestions.


Have a nice day,
--
Paco Willers <paco.willers@gmail.com>