[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: [ANN] couv - coroutine based libuv wrapper
- From: Jerome Vuarand <jerome.vuarand@...>
- Date: Mon, 5 Nov 2012 16:46:05 +0000
2012/11/5 Hiroaki Nakamura <hnakamur@gmail.com>
> I've made an experimental module named "couv".
> https://github.com/hnakamur/couv
>
> It's a coroutine based libuv wrapper.
> It uses coroutines instead of callbacks (except for Stream:listen(),
> Timer:start() and spawn()).
>
> I think the benefits of using coroutines are:
> * We can write non-blocking applications which looks like good old
> blocking codes wrapped with
> coroutine.wrap().
> Please see a tcp echo server and client example.
>
> https://github.com/hnakamur/couv/blob/master/examples/tcp-echo-server.lua
>
> https://github.com/hnakamur/couv/blob/master/examples/tcp-echo-client.lua
> * We can use pcall() to catch errors. We don't need to check every
> return value for errors.
>
> It is not finished yet and APIs may change.
> Currently example and test codes are working, though some tests fail on
> Windows.
>
> I would like to ask you what do you think about it.
I'm working on a very similar high level wrapping code to write code
blocking-style without actually blocking the Lua interpreter. It's
unfortunately not yet ready for release, but you may be interested by
the syntax since I tried to simplify it to the minimum. Below is for
example how I'd write the echo server that you give as example. It's
of a similar length to your example, but that's because of the QUIT
command handling code that's a bit harder (my lib doesn't assemble
text lines). On the other hand the network code itself is shorter.
local nb = require 'nb'
local TEST_PORT = 9123
local lt -- listening thread
lt = nb.add_thread(function()
local l = nb.tcp() -- listening socket
l:bind('*', TEST_PORT)
l:listen()
while true do
local s = l:accept() -- server socket
nb.add_thread(function()
local buffer = "\n"
while true do
local byte,msg = s:read(1)
if not byte then
break
end
s:write(byte)
-- handle QUIT
buffer = buffer..byte
if buffer:match('[\r\n]QUIT[\r\n]$') then
nb.kill_thread(lt)
l:close()
break
end
-- keep only "QUIT" and preceding newline
buffer = buffer:sub(-5)
end
s:close()
end)
end
end)
nb.run()
Note that I didn't run your example but merely read the source, so I
may have missed some feature or behaviour detail. If you want to test
it for yourself, it's on BitBucket and the LuaSocket-based back-end
should work as-is:
https://bitbucket.org/doub/nb2/src/tip/engine_luasocket/nb.lua