[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: RE: copas.sleep() problems
- From: Thijs Schreijer <thijs@...>
- Date: Mon, 30 Dec 2013 10:30:10 +0000
> -----Original Message-----
> From: lua-l-bounces@lists.lua.org [mailto:lua-l-bounces@lists.lua.org] On
> Behalf Of Paco Willers
> Sent: zaterdag 28 december 2013 15:18
> To: Lua mailing list
> Subject: copas.sleep() problems
>
> 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
It yields the coroutine and resumes it after the given number of seconds. If sleeptime < 0 then it will not be resumed until 'copas.wakeup' is explicitly called on that coroutine
> 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 = copas.receive(skt)
> 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.
That's because you used the released code, to which a bugfix was applied later which is available in the master branch on github.
I updated the docs and requested a release, see https://github.com/keplerproject/copas/pull/13
>
> 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.
The copas.step sets the timeout to smallest of; 1) the timeout given, 2) the first sleeping coroutine to wakeup. So the scheduler returns in time to restart the sleeping coroutine.
>
> I should probably use this Copas 1.2.0 function:
>
> copas.wakeup(co)
> co is the coroutine to wakeup.
No. That should only be called when you called copas.sleep(sleeptime) with a negative value for 'sleeptime'.
>
> I have no clue to from where in my program to call this function, and how to
> determine the value of co.
Use coroutine.running() inside the handler to get the coroutine of that handler. That is the value to use when waking up a coroutine.
>
> 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.
It was and it has been fixed. See github master branch
> (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.
Updated it see https://github.com/keplerproject/copas/pull/14
> (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.
CopasTimer uses the original copas.step function to process any copas activities, and hence that should make no difference (other than the bugfix applied to copas itself)
> (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().
Copas.loop is nothing but an endless loop calling copas.step, exactly the same as you did in your code.
>
> I am curious to other people's views and suggestions.
>
>
> Have a nice day,
> --
> Paco Willers <paco.willers@gmail.com>
Hth.
Thijs